Mitsos
Mitsos

Reputation: 61

Why does fscanf ignore the first string?

I am trying to make a translator. This is the part where I put all the strings from the text file on the memory. But the program ignores the first string of the text file.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct b
{
   char b[30];
}b;
int main()
{
    int d,c,i=0;
    char k[30],x;
    b *a;
    FILE *fp;
    if ((fp=fopen("translate.txt","r"))==NULL)
    {
       printf("Σφάλμα κατά το άνοιγμα του αρχείου\n");
    }
    else
    {
        while(!feof(fp))
        {
            fscanf(fp,"%s",k);
            i++;
        }
        a=malloc((i)*(sizeof(b)));
        fclose(fp);
    }
    if ((fp=fopen("translate.txt","r+"))==NULL)
    {
       printf("Σφάλμα κατά το άνοιγμα του αρχείου\n");
    }
    else
    {
        rewind(fp);
        for (c=0;c<i;c++)
       {
        fscanf(fp,"%s",a[c].b);
       }
       fclose(fp);
    }

Upvotes: 0

Views: 158

Answers (2)

user3629249
user3629249

Reputation: 16540

after applying all the comments, the resulting code is:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



int main( void )
{
    char **lines = NULL;
    size_t lineCount = 0;
    FILE *fp = NULL;

    if ((fp=fopen("translate.txt","r"))==NULL)
    {
       perror("Σφάλμα κατά το άνοιγμα του αρχείου\n");
       exit( EXIT_FAILURE );
    }


    char * inputBuf = NULL;
    size_t inputLen = 0;

    while( getline( &inputBuf, &inputLen, fp ) )
    {
        lineCount++;
        char **tempLines = realloc( lines, (lineCount+1)*sizeof( char*) );
        if( !tempLines )
        { // then realloc failed
            perror( "realloc failed");
            free( lines );
            exit( EXIT_FAILURE );
        }

        lines = tempLines;
        lines[lineCount] = strdup( inputBuf );
        lineCount++;
    }

    fclose(fp);
    free( lines );
    return 0;
} // end function: main

however, this code is not very efficient as it repeatedly calls realloc()

To fix that, initially allocate enough room in lines[] for several lines, say 10, then keep a count of how many of those pointers are being used.

When all the allocated pointers are used and need to add another line, then double the allocation via realloc().

Upvotes: 0

ameyCU
ameyCU

Reputation: 16607

1. You should write this loop (so as to check return of fscanf ) —

  for (c=0;c<i;c++)
  {
    fscanf(fp,"%s",a[c].b);
  }

as —

c=0;
while (fscanf(fp,"%29s",a[c].b) == 1 && c<i){
 ...
 c++;
}

2. Also while(!feof(fp)) is wrong, so instead use fscanf to control the loop —

while (fscanf(fp,"%29s",k)==1)
  i++;

Note — And, just to avoid confusion, give different names to your structure member and structure.

Upvotes: 2

Related Questions