Question

I'm kinda new in C so I don't know if im allowed do to the following "if" in C, my error happens in the if line but the error is a segmentation fault, that should be a uninitialized variable but i give her a value from a file...well, there is the code:

char t1, ch;
if((fscanf(f,"P%d", &t1)) == 1){

if(!((strcmp(t1,"P2")==0) || (strcmp(t1,"P5")==0))){ // error here
fprintf(stderr, "\nTipo de imagem invalido.\n");
      fclose(f);
      return NULL;
}

If anyone can help me i will appreciate... Thank you in advance!

Was it helpful?

Solution

Edit: I have rewritten answer to be complete and correct.

You are expecting to put an integer %d into a of char, which are most likely of different sizes. int is at least same size, and often bigger, so probably this is 1st place that should have blown up.

You can look at table here to figure out what format string specifier to use to match size of the variable you are reading. For a char it should be %hhd.

Also please note you use a string comparison function strcmp for a single character. Not sure why compiler did not point out type miss-match between char* and char. You could force it to work with &t1 but it could end up with memory access faults, as strcmp expects the input to be a null-terminated string, which for single character is valid only for an empty string '\0'.

Also. If you write a format string like "P%s" the P symbol will not appear in the output.

What you can do.

Sticking to the string is tricky. You could read whole string, like P3, and compare strings as you do, however you need to remember that they are null terminated. So to hold P3 you need something like char t1[3]. char t1; will certainly not hold "P3".

Also, unless your input is well formed and you are sure of, it is dangerous to read string from scanf with plain %s. You never know how long the input will be and it might end up overflowing your buffer... You should specify the length of the string to read e.g. %2s.

#include <stdio.h>
#include <stdlib.h>

#define TYPE_SIZE 2
char ch;
int size;
char t1[TYPE_SIZE+1];

int main(){

  if( (scanf("%2s", &t1) == 1)){
    printf("t1=%s", t1);
    if(!((strcmp(t1,"P2")==0) || (strcmp(t1,"P5")==0))){ // error here
      fprintf(stderr, "\nTipo de imagem invalido.\n");
      return -1;
    }
  } else fprintf(stderr, "Wrong input.\n");
 return 0;
}

Still with this if you will input P5456456, there will be no error. You would need to consume input after 1st two characters and test it. You also need to keep track of max type length. You could also change TYPE_SIZE to something extra large in advance, but it is something to look for, and buggy prone (more theoretical, but still). Whenever you change TYPE_SIZE you need to update the format string, or construct it dynamically - more code.

Personally I would probably try reading type number into an integer and construct the if vs it.

#include <stdio.h>
#include <stdlib.h>

char ch;
int size;
unsigned char t1;

int main(){

  if( (scanf("P%hhu", &t1) == 1)){
    printf("t1=%u\n", t1);
    if(!((t1 == 2) || (t1 == 5))){ // error here
      fprintf(stderr, "\nTipo de imagem invalido.\n");
      return -1;
    }
  } else fprintf(stderr, "Wrong input.\n");
 return 0;
}

OTHER TIPS

You should get segmentation fault even in

if((fscanf(f,"P%d", &t1)) == 1){

You should use

  int t1;

In strcmp, you are passing t1 which is char not const char *. Here, char value is being typecasted to a pointer and now it tries to access the value at the location of t1. And this results in segmentation fault. So change is

  int t1;

  if((fscanf(f,"P%d", t1))){

 if(!((2 == t1) || (5 == t1))){ // error here
  fprintf(stderr, "\nTipo de imagem invalido.\n");
      fclose(f);
      return NULL;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top