读取csv文件的C代码由于文件太长而崩溃

读取csv文件的C代码由于文件太长而崩溃,c,csv,C,Csv,我有一个程序,使用C编程语言读取和打印csv文件中的短语。在csv文件(点变量)中设置逗号数后输出短语的程序。csv文件是一个非常长的数据集。下面的C代码有一个问题,在一定数量的输出之后,它会给出一个错误,并在到达文件末尾之前关闭文件。除此之外,我想添加另一个字符,比如(点),称为(点2),但不是从第10个逗号开始,我希望新的点从8开始,然后再次递增7 #include<stdio.h> // fetch the phrase based on the point void fet

我有一个程序,使用C编程语言读取和打印csv文件中的短语。在csv文件(点变量)中设置逗号数后输出短语的程序。csv文件是一个非常长的数据集。下面的C代码有一个问题,在一定数量的输出之后,它会给出一个错误,并在到达文件末尾之前关闭文件。除此之外,我想添加另一个字符,比如(点),称为(点2),但不是从第10个逗号开始,我希望新的点从8开始,然后再次递增7

#include<stdio.h>

// fetch the phrase based on the point
void fetchPhrase(int point){

// create FILE pointer variable which will access the file
FILE *fp;

// read character from file
char ch;

int flagEndFile = 0;

// store phrase that is readed from file
char phrase[100];

// work as index for phrase
int index = 0;

// track the ","
int counter = 0;

// open the file in read mode
fp = fopen("input.csv", "r");

// check whether file is opened or not
if(fp == NULL){
printf("File not found!");
exit(1);
}

// read the character untill the file is not end
while((ch = fgetc(fp)) != EOF){


// check whether character is ',' or not
if(ch == ','){

// increment the counter
counter++;
}

// when we get the "," as well as correct point
if(ch == ',' && counter == point){

// read the phrase until the program does not found ","
while((ch = fgetc(fp)) != ','){

// if file is ended then break the loop
if(ch == EOF){
break;
}

// otherwise store phrase into the phrase array
phrase[index++] = ch;
}

// break the loop
break;
}
}

// store null into the character array
phrase[index] = '\0';

// check whether the point is found or not in the file
if(ch == EOF && phrase[0] == '\0'){

// point is not found in the file
printf("There is no point in the 'input' file");

}else{

// otherwise print the phrase
printf("\n Price is: %s", phrase);
}

}


void main(){

// create FILE pointer variable which will access the file
FILE *fp;

// store usr input
int point = 10;


// this loop run untill the user does not enter -999.
while(point != -999){

// call the function which display the phrase
fetchPhrase(point);
//Nexct price value is 7 commas after
point = point + 7;
//printf("The price is %d\n", point);
// get the input from the user
//printf("\nAfter what comma do you want the code to print: ");
//scanf("%d", &point);

}

// close the file
fclose(fp);

}

#包括
//根据要点提取短语
无效短语(整数点){
//创建将访问文件的文件指针变量
文件*fp;
//从文件中读取字符
char ch;
int flagndfile=0;
//存储从文件读取的短语
字符短语[100];
//用作短语的索引
int指数=0;
//跟踪“,”
int计数器=0;
//以读取模式打开文件
fp=fopen(“input.csv”,“r”);
//检查文件是否已打开
如果(fp==NULL){
printf(“未找到文件!”);
出口(1);
}
//读取字符直到文件未结束
而((ch=fgetc(fp))!=EOF){
//检查字符是否为“”
如果(ch==','){
//递增计数器
计数器++;
}
//当我们得到“,”以及正确的点
if(ch=','&&计数器==点){
//阅读短语,直到程序找不到“,”
而((ch=fgetc(fp))!=','){
//如果文件结束,则中断循环
如果(ch==EOF){
打破
}
//否则,将短语存储到短语数组中
短语[index++]=ch;
}
//打破循环
打破
}
}
//将null存储到字符数组中
短语[索引]='\0';
//检查是否在文件中找到该点
如果(ch==EOF&&PHASE[0]=='\0'){
//在文件中找不到点
printf(“输入”文件中没有点”);
}否则{
//否则,打印短语
printf(“\n价格为:%s”,短语);
}
}
void main(){
//创建将访问文件的文件指针变量
文件*fp;
//存储usr输入
int点=10;
//此循环将一直运行,直到用户未输入-999。
而(点!=-999){
//调用显示短语的函数
短语(点);
//NEXT价格值在后面是7个逗号
点=点+7;
//printf(“价格为%d\n”,点);
//从用户那里获取输入
//printf(“\n在代码要打印的逗号之后:”);
//scanf(“%d”点和“&point”);
}
//关闭文件
fclose(fp);
}

我在
fetchPhrase()
中看到的一个大问题是,当您找到所需的
时,您将逗号作为
短语的一部分来读取。我看到的下一个大问题是,由于您使用的是
fgetc()
,因此您没有检查
'\n'
。因此,例如,当您更新
point=point+7
且当前记录(行)中剩余的字段数少于该数量时,您将读取并忽略
“\n”
,并开始尝试从下一行读取字段。由于
'\n'
不是
,“
您从不增加
计数器
,因此从下一行开始读取时,字段计数将关闭

现在很难知道如何处理您对“point”的所有请求,如果它包装并从下一行开始阅读,而没有详细的解释,但是如果您要求的字段多于行中的字段,则返回听起来是合理的,并且可以使用类似的方法来完成:

#define PHRASE 100

int fetchPhrase (int point, FILE *fp)
{
    char phrase[PHRASE] = "";           /* buffer to hold phrase */
    int ch,                             /* current character */
        index = 0,                      /* phrase index */
        counter = 0;                    /* separator counter */
    
    /* read all chars in line */
    while ((ch = fgetc (fp)) != '\n' && ch != EOF) {
        /* check if wanted field (point) found */
        if (counter == point) {
            /* protect phrase bounds, while not next separator */
            while (index + 1 < PHRASE && ch != ',' && ch != '\n' && ch != EOF) {
                phrase[index++] = ch;   /* store character in phrase */
                ch = fgetc (fp);
            }
            phrase[index] = '\0';       /* nul-terminate */
            break;                      /* break read loop */
        }
        if (ch == ',')                  /* comma found */
            counter++;                  /* increment counter */
    }
    
    if (counter == point && phrase[0] != 0)     /* phrase found */
        printf ("\n Price is: %s\n", phrase);
    else
        fputs ("There is no point in line.\n", stderr);

    return ch;  /* return stream state good (>0) if not EOF */
}
现在,您可以将指向函数的open
FILE*
指针作为参数传递——函数可以依赖于文件已打开并已验证打开以供调用方读取的事实:

    fetchPhrase (point, fp);
您还可以使用返回来确定是否已达到
EOF

    while (fetchPhrase (point, fp) != EOF) {
        ...
    }
使用面向行的方法

虽然可以使用
fgetc()
,但它会使读取输入文件中的记录(行)变得复杂。如果改为使用面向行的输入函数(如
fgets()
或POSIX
getline()
)读取每一行,然后,处理文件中字段的偏移量请求将仅限于行中包含的字段,并且将消除对
'\n'
的测试,从而将字段请求限制到单个记录


这就是我对你的密码的想法。仔细检查一下,如果您还有其他问题,请告诉我。

charch应为
int ch
以正确检测
EOF
。请正确缩进代码,使其可读。如果
int点=10while()
中,你
point=point+7
它如何与
-999
相等?除非您是在独立环境(没有任何操作系统的好处)中编程,否则在符合标准的实现中,
main
的允许声明是
int main(void)
int main(int argc,char*argv[])
(您将看到它是用等效的
char**argv
编写的)。请参见:@DavidC.Rankin我无法实现
char ch
,因为它存储变量,-999只是一个数字,while循环可以永远运行,因为它永远不会达到-999。不,我的意思是将声明从
char ch
更改为
int ch
。请参见
getchar()的正确返回类型是什么
?这是有原因的,当我做出更改时,它仍然不幸崩溃。
    while (fetchPhrase (point, fp) != EOF) {
        ...
    }