gpt4 book ai didi

c - 我不知道为什么我的代码中出现段错误

转载 作者:行者123 更新时间:2023-11-30 20:18:08 24 4
gpt4 key购买 nike

在代码中,我尝试读取一个文件,然后用 strtok 将其除以获取目录的 id(8 个字符)以及我想要传递到该目录的文件类型(A、B、C. pdf)。然后我使用函数系统来执行相应的命令。我知道在 txt 文件中,首先是目录的 id,然后是文件类型。我在编译时没有任何问题,但是当我执行程序时,出现段错误,我不知道为什么。

#include <stdio.h>
#include <stdlib.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>


int main(int argc, char* argv[]){

char ch, str[999], id[8], command[25];
FILE *fp;
int i = 0;
char *pch;

fp = fopen("p1.text", "r");

if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}

while((ch = fgetc(fp)) != EOF){

str[i] = ch;
i++;

}
pch = strtok(str, " ,.-\n");

while(pch != NULL){
if(isalpha(pch)){
sprintf(command, "cp %s.pdf %s", pch, id);
system(command);
strcpy(command, "");
}
if(strlen(pch) == 8){
strcpy(id, pch);
}
pch = strtok(NULL, " ,.-\n");
}

fclose(fp);

return 0;
}

最佳答案

id 变量不够大,无法保存需要存储的值。

C 中的字符串以 null 结尾。所以8个字符的字符串需要9个字节的存储空间。 id 只有 8 个元素长,因此当您复制到它时,您会写到数组末尾。在数组边界之外写入会调用 undefined behavior在这种情况下,这会导致您的代码崩溃。

使 id 长度为 9 个元素,而不是 8 个:

int id[9];

您也没有正确存储 fgetc 的结果。您将 ch 声明为 char,但 fgetc 返回 int。这是区分 EOF 和普通字符值所必需的。因此将 ch 的类型更改为 int

此外,通过一次读入整个文件,然后在循环中使用一个内部状态机来调用 strtok 来找出哪个元素,会让事情变得比需要的更复杂一些你正在阅读。

您可以通过使用 fgets 一次读取一行来简化此过程,然后调用 strtok 一次以获取 id 并再次调用获取pch:

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

int main()
{
char line[100], command[100];
FILE *fp;
char *pch, *id;

fp = fopen("p1.text", "r");

if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}

while (fgets(line, sizeof(line), fp)) {
id = strtok(line, " \n");
if (!id) continue;

pch = strtok(NULL, " \n");
if (!pch) continue;

snprintf(command, sizeof(command), "cp %s.pdf %s", pch, id);
//printf("command=%s\n", command);
system(command);
}

fclose(fp);

return 0;
}

关于c - 我不知道为什么我的代码中出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54951171/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com