实际上,下面的程序是分割字符串并显示输出。我已经完成了我的程序并且它提供了所需的输出。但是,最后它给出了分段错误。我也尝试使用调试器。但是,我无法找到问题。任何人都可以帮助我吗?
Vivek|Raj|20 Abi|Nila|20
Vivek's last name Raj and age is 20. Abi's last name Nila and age is 20.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person{
char firstname[30];
char lastname[30];
int age;
};
int main(int args, char *argv[])
{
struct person list[30];
int i,n;
char *ch,*ch1,*ch2,*ch3;
char buf[256];
FILE *fp;
fp = fopen(argv[1],"r");
if(fp == NULL){
printf("Cannot open file %s\n", argv[1]);
exit(0);
}
i=0;
fgets(buf,256,fp);
while(!feof(fp)){
ch = strchr(buf,'\n');
if(ch != NULL) *ch = '\0';
else break;
ch = strchr(buf,'|');
ch2 = strrchr(buf,'|');
if(ch != NULL)
{
*ch = '\0';ch1 = ++ch2;
}
else break;
ch++;
strcpy(ch3,ch);
ch2=strchr(ch3,'|');
*ch2='\0';
strcpy(list[i].firstname,buf);
strcpy(list[i].lastname,ch3);
list[i].age = atoi(ch1);
i++;
fgets(buf,256,fp);
}
n = i;
for (i = 0; i < n; i++)
printf("%s's last name %s and age.\n",list[i].firstname,list[i].lastname,list[i].age);
return 0;
}
答案 0 :(得分:1)
作为第一点,你读错了。您应该循环fgets()
,因为它在失败时返回NULL
(通常,这意味着您已到达文件末尾):
char buf[256];
while(fgets(buf, sizeof buf, fp))
{
/* process each line here */
}
答案 1 :(得分:1)
你正在做一个strcpy(ch3,ch);其中ch3没有被分配任何内存,因为它也没有被分配给NULL,你的代码会覆盖一些未知的内存,导致内存损坏并最终导致崩溃。
答案 2 :(得分:0)
您的代码可能崩溃的原因有很多。
1)在我看来,ch3根本没有初始化。所以它可能包含垃圾和点(偶然)到可写内存(可能是堆栈?)。在使用之前,应该将指向有效缓冲区的指针分配给ch3。我认为崩溃是由于这个问题。可能的纠正(不是最好的纠正)是:
char tmp[256];
char *ch3;
// Make ch3 point to a valid buffer
ch3 = tmp;
// ...
// Here ch3 must point to a valid location!!!
strcpy(ch3,ch);
2)顺便说一下,根本不需要第二个缓冲区:你可以查找两个分隔符,用终止字符替换它们,并直接从原始缓冲区中获取指向三个字符串的指针:
ch = strchr(buf,'|');
if (ch == NULL)
{
// INPUT MALFORMED
break;
}
*ch = '\0'; // This splits first and second+third
++ch;
// Now ch points to the second+third field!
ch2 = strrchr(ch,'|');
if(ch2 == NULL)
{
// INPUT MALFORMED
break;
}
*ch2 = '\0'; // split second and third
++ch2;
// Now ch2 points to the third field!
//
printf("First name=%s Last name=%s age=%s\n",buf,ch,ch2);
3)程序限制为30个项目,但实际插入的元素数量不会在任何地方检查(类似
//...
++i;
if (i >= 30) {
break;
}
当然,如果“list”数组的大小是通过宏参数化的话会很好。
4)“firstname”和“lastname”是char [SOME_SIZE]。所有输入字段是否都适合SOME_SIZE-1?
一般来说,程序错过了一些“限制”和“输入验证”控件(例如,如果数字字段格式不正确怎么办?好吧,它不会崩溃,但是......嗯......)
我希望这可能有所帮助。
此致
答案 3 :(得分:0)
您的printf语句不正确:
for (i = 0; i < n; i++)
printf("%s's last name %s and age.\n",list[i].firstname,list[i].lastname,list[i].age);
return 0;
你错过了最后一个参数的%d。它应该是:
for (i = 0; i < n; i++)
printf("%s's last name %s and age is %d.\n",list[i].firstname,list[i].lastname,list[i].age);
return 0;