如何使用strtok()从文本文件中读取并创建结构?

时间:2021-02-11 07:15:52

Given a text file:

给定一个文本文件:

I Angelina Jolie 1 7728323
I Mel Gibson 3 7809606 7733889 7724609
I Robert Redford 2 7721170 7731959
I Jennifer Aniston 4 2188989 2189898 2181020 2183456
I Jami Gertz 4 7734404 7774012 7773023 7921492
I Brad Pitt 2 7774017 7878485
R Sylvester Stallone 0 
I Victoria Principal 3 7933045 7771234 7820987
R Jennifer Aniston 0
R Sean Penn 0
I Kevin Costner 1 7874014
Q

I need to read each line, separate the values by spaces, and create structs of each one. My current code is:

我需要读取每一行,用空格分隔值,并创建每个行的结构。我目前的代码是:

int main(){
int y;
FILE *data;
char action;
char line[100];
int counter = 0;
int index = 0;

struct number{
    int phoneNumber;
    struct number *next;
};

struct contact{
    char fName[10];
    char lName[10];
    struct number *start;
};  

struct number numbers[50];
struct contact directory[10];

if((data=fopen("hw6data.txt", "r")) != NULL){
    while(fscanf(data, "%s", line) != EOF){
        char s[2] = " ";
        char *token;

        token = strtok(line, s);

        while(token != NULL){
            if(counter==0){
                if(s == "I") {
                    if(counter==1){
                        strcpy(directory[index].fName, s);
                    }
                    if(counter==2){
                        strcpy(directory[index].lName, s);
                    }
                }
            }
            token = strtok(NULL, s);
        }
    }
}

for(y = 0; y < 10; y++){
    printf("%s ", directory[y].fName);
    printf("%s\n", directory[y].lName);
}

fclose(data);
return 1;

}

}

I'm trying to create a struct for each phone contact. The I or R indicates whether I should insert the contact or remove it. The directory is an array that contains up to 10 contacts. I can hold a total of 50 numbers. Each contact struct holds a pointer that should point to the first number in the numbers array of number structs. I'm creating an array-based linked list. I thought this code should create the contact structs. It compiles, but when I run it I get:

我正在尝试为每个手机联系人创建一个结构。 I或R表示我是应该插入触点还是将其移除。该目录是一个包含最多10个联系人的数组。我总共可以容纳50个号码。每个联系人结构都包含一个指针,该指针应指向数字结构的数字数组中的第一个数字。我正在创建一个基于数组的链表。我认为这段代码应该创建联系结构。它编译,但当我运行它我得到:

 ��f
 �
ɷ� 
�E 

����� 
 �
�� 
.N=� 
 |�X�|���^�
� 
Segmentation fault

Help?

帮帮我?

2 个解决方案

#1


1  

An example that parse the "I" lines and print what's was read :

解析“I”行并打印读取内容的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    int y;
    FILE *data;
    char action;
    char line[100];
    int counter = 0;
    int index = 0;


    struct contact{
    char fName[10];
    char lName[10];
    };  

    struct contact directory[10];

    if((data=fopen("hw6data.txt", "r")) != NULL){
        while(fgets(line,sizeof(line),data)){
            char s[2] = " ";
            char *token = strtok(line, s);

            while(token != NULL) {
                if(strcmp(token,"I")==0) {
                    counter = 0;
                }
                if(counter==1) {
                    strcpy(directory[index].fName, token);
                }
                if(counter==2) {
                    strcpy(directory[index].lName, token);
                    index++;
                }
                counter++;
                token = strtok(NULL, s);
            }
        }
    }

    for(y = 0; y < index; y++){
        printf("%s ", directory[y].fName);
        printf("%s\n", directory[y].lName);
    }

    fclose(data);
    return 1;
}

If it helps...

如果它有帮助......

#2


0  

A few problems I can see just at a glance (not necessarily a complete list):

我可以一目了然地看到一些问题(不一定是完整的清单):

  • The line while (fscanf(data, "%s", line) != EOF) does not read in an entire line at a time (which appears to be your intent, since you named your variable line). You probably want to do while (fgets(data, 100, line) != NULL) instead.
  • 行(fscanf(数据,“%s”,行)!= EOF)一次不读取整行(这似乎是你的意图,因为你命名了变量行)。你可能想要做(fgets(数据,100,行)!= NULL)而不是。
  • You can't do string comparison in C as if (s == "I"). If you're just checking the first character, you can do if (s[0] == 'I') (note that single quote marks ('') are used here to denote a character literal, versus the double quote marks ("") used to denote string literals.
  • 您不能在C中进行字符串比较,如果(s ==“I”)。如果您只是检查第一个字符,则可以执行if(s [0] =='I')(请注意,此处使用单引号('')表示字符文字,而不是双引号( “”)用于表示字符串文字。
  • You have if (counter == 1) and if (counter == 2) nested inside if (counter == 0), so those conditions will never be true, unless you modify counter at some point after the if (counter == 0) and before the if (counter == 1).
  • 你有if(counter == 1)和if(counter == 2)嵌套在if(counter == 0)里面,所以这些条件永远不会成立,除非你在if之后的某个点修改counter(counter == 0 )和if之前(计数器== 1)。
  • counter and index are never being incremented, so your entire while loop is having no effect whatsoever on the directory array. This is why you get garbage when you try to print out its values.
  • 计数器和索引永远不会递增,因此整个while循环对目录数组没有任何影响。这就是为什么在尝试打印其值时会出现垃圾的原因。

#1


1  

An example that parse the "I" lines and print what's was read :

解析“I”行并打印读取内容的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    int y;
    FILE *data;
    char action;
    char line[100];
    int counter = 0;
    int index = 0;


    struct contact{
    char fName[10];
    char lName[10];
    };  

    struct contact directory[10];

    if((data=fopen("hw6data.txt", "r")) != NULL){
        while(fgets(line,sizeof(line),data)){
            char s[2] = " ";
            char *token = strtok(line, s);

            while(token != NULL) {
                if(strcmp(token,"I")==0) {
                    counter = 0;
                }
                if(counter==1) {
                    strcpy(directory[index].fName, token);
                }
                if(counter==2) {
                    strcpy(directory[index].lName, token);
                    index++;
                }
                counter++;
                token = strtok(NULL, s);
            }
        }
    }

    for(y = 0; y < index; y++){
        printf("%s ", directory[y].fName);
        printf("%s\n", directory[y].lName);
    }

    fclose(data);
    return 1;
}

If it helps...

如果它有帮助......

#2


0  

A few problems I can see just at a glance (not necessarily a complete list):

我可以一目了然地看到一些问题(不一定是完整的清单):

  • The line while (fscanf(data, "%s", line) != EOF) does not read in an entire line at a time (which appears to be your intent, since you named your variable line). You probably want to do while (fgets(data, 100, line) != NULL) instead.
  • 行(fscanf(数据,“%s”,行)!= EOF)一次不读取整行(这似乎是你的意图,因为你命名了变量行)。你可能想要做(fgets(数据,100,行)!= NULL)而不是。
  • You can't do string comparison in C as if (s == "I"). If you're just checking the first character, you can do if (s[0] == 'I') (note that single quote marks ('') are used here to denote a character literal, versus the double quote marks ("") used to denote string literals.
  • 您不能在C中进行字符串比较,如果(s ==“I”)。如果您只是检查第一个字符,则可以执行if(s [0] =='I')(请注意,此处使用单引号('')表示字符文字,而不是双引号( “”)用于表示字符串文字。
  • You have if (counter == 1) and if (counter == 2) nested inside if (counter == 0), so those conditions will never be true, unless you modify counter at some point after the if (counter == 0) and before the if (counter == 1).
  • 你有if(counter == 1)和if(counter == 2)嵌套在if(counter == 0)里面,所以这些条件永远不会成立,除非你在if之后的某个点修改counter(counter == 0 )和if之前(计数器== 1)。
  • counter and index are never being incremented, so your entire while loop is having no effect whatsoever on the directory array. This is why you get garbage when you try to print out its values.
  • 计数器和索引永远不会递增,因此整个while循环对目录数组没有任何影响。这就是为什么在尝试打印其值时会出现垃圾的原因。