C 使用strtok时出现Seg故障
我试图从如下输入中读取每个数字:C 使用strtok时出现Seg故障,c,segmentation-fault,strtok,C,Segmentation Fault,Strtok,我试图从如下输入中读取每个数字: 179 2358 5197 867 5541 172 4294 1397 2637 136 3222 591 。。。然后一行一行地得到每一行的最小值/最大值,然后使用strtok得到每一行中的数字,但是我在第二个while循环中得到了一个seg故障错误 守则: #include "header.h" #include <string.h> int main(void) { int8_t* line =
179 2358 5197 867
5541 172 4294 1397
2637 136 3222 591
。。。然后一行一行地得到每一行的最小值/最大值,然后使用strtok得到每一行中的数字,但是我在第二个while循环中得到了一个seg故障错误
守则:
#include "header.h"
#include <string.h>
int main(void) {
int8_t* line = malloc(sizeof(int8_t) * 75);
int8_t* temp;
int32_t minim, maxim;
int32_t current;
stdin = fopen("stdin", "r");
while (fgets(line, 75 * sizeof(int8_t), stdin)) {
printf("%s", line);
temp = strtok(line," \n\t");
maxim = minim = atoi(temp);
while (temp != NULL) {
current = atoi(temp);
temp = strtok(NULL, " \n\t");
if (current < minim)
minim = current;
if (current > maxim)
maxim = current;
}
printf("\nMin and max: %d %d\n", minim, maxim);
}
printf("\n");
return 0;
}
#包括“header.h”
#包括
内部主(空){
int8_t*line=malloc(sizeof(int8_t)*75);
内部温度;
int32_t最小值,最大值;
int32_t电流;
stdin=fopen(“stdin”、“r”);
而(fgets(线条,75*sizeof(int8_t),标准尺寸)){
printf(“%s”,第行);
temp=strtok(第“\n\t”行);
最大值=最小值=原子(温度);
while(temp!=NULL){
电流=atoi(温度);
temp=strtok(空,“\n\t”);
如果(电流<最小值)
最小值=电流;
如果(当前>最大值)
最大值=电流;
}
printf(“\n最小值和最大值:%d%d\n”,最小值和最大值);
}
printf(“\n”);
返回0;
}
标题:
#ifndef HEADER_H
# define HEADER_H
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
typedef char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long long int int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
#endif
#ifndef头
#定义标题
#包括
#包括
#包括
typedef char int8_t;
typedef签名短整型16_t;
typedef签名int int32_t;
typedef签名长整型64_t;
typedef无符号字符uint8;
typedef无符号短整数uint16\u t;
typedef unsigned int uint32\u t;
typedef无符号长整数uint64\u t;
#恩迪夫
我只是不明白这可能是错的。谢谢
stdin = fopen("stdin", "r");
这不是你想象的那样。这将尝试打开当前目录中名为“stdin”的文件。它不打开标准输入流
您很可能没有此名称的文件,因此此函数可能会失败并返回NULL。因为不检查返回值,所以将空指针传递给fgets
。这将调用未定义的行为,在本例中表现为崩溃
程序启动时,标准输入流已打开。因此,删除fopen
调用,它应该会工作。好的,所以
在我的编译器上中断,因为它重新定义了标准保留的标识符int8\t
等。(编译器抱怨的不太正确,因为没有包含相关的头,但您有。)如果您定义自己的类型,请使用自己的标识符。或者将
包含在“真实”intX\t类型中(是的,我知道某个“大”编译器没有该头)char*
,而不是int8\t*
。(有符号的char
是由实现定义的,无论如何,一个好的编译器会大声抱怨没有使用char*
的许多隐式强制转换。)minim
和maxim
,您使用了确切的宽度类型int32\t
,但忽略了使用适当的printf()
宽度说明符来配合(PRId32
,在
中指定)。由于我看不到对精确宽度类型的任何具体需求,我将它们替换为普通的int
(仅%d
就足够了)sizeof(char)
,因为这是定义1
fopen()
可能会失败。确保没有stdin
是来自终端还是来自文件或管道取决于您如何调用可执行文件。如果打开文件,请使用文件*句柄\u名称
,而不是stdin
。此外,stdin
是一个打开的文件描述符(即程序的标准输入),因此您必须使用freopen()
,而不是fopen()
,才能正确地从其他源接收它。最简单的事情是按原样实际使用stdin
(这也为您使用程序提供了最大的灵活性)#include <stdlib.h> // <-- added
#include <stdio.h> // <-- added
#include <string.h>
int main() {
char* line = malloc(75); // <-- turned to char *
char* temp; // <-- turned to char *
int minim, maxim; // <-- turned to int
int current; // <-- turned to int
while (fgets(line, 75, stdin)) { // <-- using stdin directly
printf("%s", line);
temp = strtok(line," \n\t");
maxim = minim = atoi(temp);
while (temp != NULL) {
current = atoi(temp);
temp = strtok(NULL, " \n\t");
if (current < minim)
minim = current;
if (current > maxim)
maxim = current;
}
printf("\nMin and max: %d %d\n", minim, maxim);
}
printf("\n");
free( line ); // <-- releasing memory
return 0;
}
#include//您不需要打开stdin
,它已经打开了。是否有任何理由不在此处使用scanf
?给定简单而规则的输入。stdin=fopen(“stdin”,“r”)代码>--正在打开一个名为“stdin”的文件进行读取。在从stdin
句柄读取之前,也不会检查打开该文件是否成功。未定义的行为,你会死。@WeatherVane:经常建议使用fgets()
一次读取一行并在内存中解析它(而不是*scanf()
)。这里没有批评的理由(如果他做得对就好了)。在检查temp
上的atoi
之前,先检查它是否为NULL
。未定义的行为会导致死亡。uint8\u t
等是标准库(
)保留的标识符,使用一致性编译器编译头.h会因此失败。@Marcus:您没有检查。@DevSolar这不是错误。它正确地读取了第一行,然后它就断了,我忘了在帖子中写这个……还要注意,你不一定能像那样重新分配stdin
。在现代Linux上,您可能可以。在经典的Unix上,它可能不起作用。这就是为什么该函数是标准C的一部分(尽管我链接到POSIX规范)。不,字符没有定义为8位,而是定义为具有char\u位
位。我保留OP的源代码格式是为了让更改对他来说更加突出(源代码格式是o的问题)
./testme.exe < file.dat # feeding file.dat to stdin
179 2358 5197 867
Min and max: 179 5197
5541 172 4294 1397
Min and max: 172 5541
2637 136 3222 591
Min and max: 136 3222