seyfu-t
seyfu-t

Reputation: 1

Can't compare Lines of a file in C

I got this piece of code:

void scanLinesforArray(FILE* file, char search[], int* lineNr){
    char line[1024];
    int line_count = 0;
    while(fgets(line, sizeof(line),file) !=NULL){
        ++line_count;
        printf("%d",line_count);
        printf(line);
        char *temp = malloc(strlen(line));
//      strncpy(temp,line,sizeof(line));
//      printf("%s\n",temp);
        free(temp);
        continue;
    }
}

This will print all lines of the file, but as soon as I uncomment the strncpy(), the program just stops without error.

Same happens as soon as I use strstr() to compare the line to my search variable.

I tried the continue statement and other redundant things, but nothing helps.

Upvotes: 0

Views: 60

Answers (1)

chux
chux

Reputation: 154562

Many problems:

Do not print a general string as a format

Code risks undefined behavior should the string contain a %.

// printf(line);  // BAD

printf("%s", line);
// or 
fputs(line, stdout);

Bad size

strncpy(temp,line,sizeof(line)); is like strncpy(temp,line, 1024);, yet temp points to less than 1024 allocated bytes. Code attempts to write outside allocated memory. Undefined behavior (UB).

Rarely should code use strncpy().

Bad specifier

%s expects a match string. temp does not point to a string as it lacks a null character. Instead allocated for the '\0'.

// printf("%s\n", temp);`.  

char *temp = malloc(strlen(line) + 1); // + 1
strcpy(temp,line);
printf("<%s>", temp);
free(temp);

No compare

"Can't compare Lines of a file in C" is curious as there is no compare code.

Recall fgets() typically retains a '\n' in line[].


Perhaps

long scanLinesforArray(FILE* file, const char search[]){
  char line[1024*4];    // Suggest wider buffer - should be at least as wide as the search string.
  long line_count = 0;  // Suggest wider type
  while(fgets(line, sizeof line, file)) {
    line_count++;
    line[strcspn(line, "\n")] = 0; // Lop off potential \n
    if (strcmp(line, search) == 0) {
      return line_count;
    }
  }
  return 0; // No match
}

Advanced: Sample better performance code.

long scanLinesforArray(FILE *file, const char search[]) {
  size_t len = strlen(search);
  size_t sz = len + 1;
  if (sz < BUFSIZ) sz = BUFSIZ;
  if (sz > INT_MAX) {
    return -2; // Too big for fgets()
  }
  char *line = malloc(sz);
  if (line == NULL) {
    return -1;
  }

  long line_count = 0;
  while (fgets(line, (int) sz, file)) {
    line_count++;
    if (memcmp(line, search, len) == 0) {
      if (line[len] == '\n' || line[len] == 0) {
        free(line);
        return line_count;
      }
    }
  }

  free(line);
  return 0; // No match
}

Upvotes: 4

Related Questions