Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 防止超过30个字符的输入_C - Fatal编程技术网

C 防止超过30个字符的输入

C 防止超过30个字符的输入,c,C,嗨,我的代码有问题。我需要它运行,这样,如果用户为“fileName”变量输入超过30个字符,它将“return”;但是下面的代码不起作用。有什么想法吗 FILE *packetFile; //initialize file handle char fileName[30]; //initialize int i; int length = 0; length = strlen(fileName); getchar(); printf("Please enter a file name (M

嗨,我的代码有问题。我需要它运行,这样,如果用户为“fileName”变量输入超过30个字符,它将“return”;但是下面的代码不起作用。有什么想法吗

FILE *packetFile; //initialize file handle
char fileName[30]; //initialize
int i;
int length = 0;

length = strlen(fileName);
getchar();

printf("Please enter a file name (Maxium 30 characters): ");
fgets(fileName, 30, stdin);
sscanf(fileName, "%s", fileName);

if(fileName[0] == '\n'){
    return;
}

if(strlen(fileName) > 30)
    return;

if((packetFile = fopen(fileName,"w"))==NULL) {

    printf("Unable to open the file: %s\n",fileName);

} else {

    printf("%d packets have been saved to file named %s", pCount, &fileName);

    for(i=0;i<pCount;i++) {

     fprintf(packetFile,"%04i:%04i:%04i:%04i:%s\r\n",pRecords[i].source,pRecords[i].destination,pRecords[i].type,pRecords[i].port,pRecords[i].data);

    }

        fclose(packetFile);

}
文件*packetFile//初始化文件句柄
字符文件名[30]//初始化
int i;
整数长度=0;
长度=strlen(文件名);
getchar();
printf(“请输入文件名(最多30个字符):”;
fgets(文件名,30,标准输入法);
sscanf(文件名,“%s”,文件名);
如果(文件名[0]='\n'){
返回;
}
如果(strlen(文件名)>30)
返回;
if((packetFile=fopen(文件名,“w”))==NULL){
printf(“无法打开文件:%s\n”,文件名);
}否则{
printf(“%d个数据包已保存到名为“%s”、pCount和fileName”的文件中);

因为(i=0;i多个原因。您只分配了30个字符的空间,因此在您的情况下,
strlen
将永远不会返回结果
>30
。您在
fgets
调用中最多只能读取30个字符

一个可能的解决方案是分配更多的空间开始使用
strlen
。另一个解决方案是保持有限的分配,并使用循环从
stdin
读取单个字符-如果您没有及时到达换行符,您只需中断并返回即可

在POSIX系统上,
getline
提供了一个简洁的解决方案。它读取整行,并返回长度。唯一需要记住的是
getline
在堆上分配内存,因此在完成后需要释放内存

大致如下:

char *filename = NULL;
size_t linecap = 0; // These initial values tells getline to allocate as much space as needed
ssize_t linelen = getline(&filename, &linecap, stdin);
if (linelen < 0)
    ...
if (linelen > 30)
    // Treat as error or whatever

free(filename);
char*filename=NULL;
size\u t linecap=0;//这些初始值告诉getline根据需要分配尽可能多的空间
ssize_t linelen=getline(&filename,&linecap,stdin);
if(linelen<0)
...
如果(linelen>30)
//视为错误或任何东西
免费(文件名);

(无耻地从手册页借用)

多个原因。您只分配了30个字符的空间,因此在您的情况下,
strlen
将永远不会返回结果
>30
。您的
fgets
调用中最多只能读取30个字符

一个可能的解决方案是分配更多的空间开始使用
strlen
。另一个解决方案是保持有限的分配,并使用循环从
stdin
读取单个字符-如果您没有及时到达换行符,您只需中断并返回即可

在POSIX系统上,
getline
提供了一个简洁的解决方案。它读取整行,并返回长度。唯一需要记住的是
getline
在堆上分配内存,因此在完成后需要释放内存

大致如下:

char *filename = NULL;
size_t linecap = 0; // These initial values tells getline to allocate as much space as needed
ssize_t linelen = getline(&filename, &linecap, stdin);
if (linelen < 0)
    ...
if (linelen > 30)
    // Treat as error or whatever

free(filename);
char*filename=NULL;
size\u t linecap=0;//这些初始值告诉getline根据需要分配尽可能多的空间
ssize_t linelen=getline(&filename,&linecap,stdin);
if(linelen<0)
...
如果(linelen>30)
//视为错误或任何东西
免费(文件名);

(无耻地从手册页上借来)

太棒了。我该怎么做呢?我需要包括任何专门的图书馆吗@Henrik@Henrik注:
getline()
在C语言中不是一个标准函数,但我认为它在POSIX.Brilliant中。我该怎么做呢?我需要为此包含任何特殊的库吗@Henrik@Henrik注:
getline()
在C语言中不是一个标准函数,但我认为它在POSIX中。您应该更清楚地说明哪些函数不能按预期/喜欢的方式工作。您应该更清楚地说明哪些函数不能按预期/喜欢的方式工作。鉴于存在
长度
为0的异常情况,如果(length&&fileName[length-1]!='\n'){
如果在fgets中输入的长度变为0,则阻止UB?@chux。输入的EOF?如果strlen在fgets中接收EOF,则不要满足,因为它是垃圾。因此,我想保护strlen(length)的值没有意义。同意
fgets()
返回NULL表示
文件名中的垃圾
文件名[0]
可以是
\0
带管道的
标准输入或键盘,允许输入
\0
fgets()
\n
上停止,但在
\0
上不停止。如果
大小(文件名)
was 1-但不在您的情况下。@您这样做的目的是输入文件名吗?为什么?鉴于存在
length
为0的异常情况,如果(length&&fileName[length-1]!='\n',您认为这样做有用吗{
如果在fgets中输入的长度变为0,则防止UB?@chux。输入的EOF?如果strlen在fgets中接收EOF,则不要满足,因为它是垃圾。因此,我想保护strlen(长度)的值没有意义。同意
fgets()
返回NULL表示
文件名中的垃圾
可以使用管道
\0
标准DIN
或允许输入
\0
fgets()
的键盘
\n
停止,但不在
\0
上。此外,如果
大小(文件名)
为1,则不在您的情况下。@chux您这样做是为了输入文件名吗?为什么?