Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
375 views
in Technique[技术] by (71.8m points)

fread - Read files separated by tab in c

I am really new to C, and the reading files thing drives me crazy... I want read a file including name, born place and phone number, etc. All separated by tab

The format might be like this:

Bob Jason   Los Angeles    33333333
Alice Wong  Washington DC  111-333-222

So I create a struct to record it.

typedef struct Person{
    char name[20];
    char address[30];
    char phone[20];
} Person;

I tried many ways to read this file into struct but it failed. I tired fread:

read_file = fopen("read.txt", "r");
Person temp;
fread(&temp, sizeof(Person), 100, read_file);
printf("%s %s %s 
", temp.name, temp.address, temp.phone);

But char string does not recorded into temp separated by tab, it read the whole file into temp.name and get weird output.

Then I tried fscanf and sscanf, those all not working for separating tab

fscanf(read_file, "%s %s %s", temp.name, temp.address, temp.phone);

Or

fscanf(read_file, "%s%s%s", temp.name, temp.address, temp.phone);

This separates the string by space, so I get Bob and Jason separately, while indeed, I need to get "Bob Jason" as one char string. And I did separate these format by tab when I created the text file.

Same for sscanf, I tried different ways many times...

Please help...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I suggest:

  1. Use fgets to read the text line by line.
  2. Use strtok to separate the contents of the line by using tab as the delimiter.


// Use an appropriate number for LINE_SIZE
#define LINE_SIZE 200
char line[LINE_SIZE];

if ( fgets(line, sizeof(line), read_file) == NULL )
{
   // Deal with error.
}

Person temp;
char* token = strtok(line, "");
if ( token == NULL )
{
   // Deal with error.
}
else
{
   // Copy token at most the number of characters
   // temp.name can hold. Similar logic applies to address
   // and phone number.

   temp.name[0] = '';
   strncat(temp.name, token, sizeof(temp.name)-1);
}

token = strtok(NULL, "");
if ( token == NULL )
{
   // Deal with error.
}
else
{
   temp.address[0] = '';
   strncat(temp.address, token, sizeof(temp.address)-1);
}

token = strtok(NULL, "
");
if ( token == NULL )
{
   // Deal with error.
}
else
{
   temp.phone[0] = '';
   strncat(temp.phone, token, sizeof(temp.phone)-1);
}

Update

Using a helper function, the code can be reduced in size. (Thanks @chux)

// The helper function.
void copyToken(char* destination,
               char* source,
               size_t maxLen;
               char const* delimiter)
{
    char* token = strtok(source, delimiter);
    if ( token != NULL )
    {
       destination[0] = '';
       strncat(destination, token, maxLen-1);
    }
}

// Use an appropriate number for LINE_SIZE
#define LINE_SIZE 200
char line[LINE_SIZE];

if ( fgets(line, sizeof(line), read_file) == NULL )
{
   // Deal with error.
}

Person temp;   
copyToken(temp.name, line, sizeof(temp.name), "");
copyToken(temp.address, NULL, sizeof(temp.address), "");
copyToken(temp.phone, NULL, sizeof(temp.phone), "
");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...