在以下代码段中,我使用stdin
和fgets()
从strtol
获取两个输入。两个输入保存在不同的变量中。为了读入用户输入,我需要为fgets()
和strtol()
添加几个变量。以下是对fgets()
和strtol()
两次调用使用不同变量的详细解决方案:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
long int m_row;
long int n_col;
char rows_save[sizeof(long int)];
char *ptr_rows_save;
printf("Enter number of rows:\n");
if (fgets(rows_save, sizeof(rows_save), stdin) != NULL)
{
m_row = strtol(rows_save, &ptr_rows_save, 10);
}
char cols_save[sizeof(long int)];
char *ptr_cols_save;
printf("Enter number of columns:\n");
if (fgets(cols_save, sizeof(cols_save), stdin) != NULL)
{
n_col = strtol(cols_save, &ptr_cols_save, 10);
}
return EXIT_SUCCESS;
}
正如您所看到的,我正在为程序从stdin接收的每个数字使用一个新数组和一个指向数组的新指针。我试图避免这个用于锻炼目的(或者为了这个问题而欢乐)。为了实现这一点,我使用一个char数组和一个指向数组的单个指针,但保持对fgets()
和strtol()
的两次单独调用:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
long int m_row;
long int n_col;
char save[sizeof(long int)];
char *ptr_save;
printf("Enter number of rows:\n");
if (fgets(save, sizeof(save), stdin) != NULL)
{
m_row = strtol(save, &ptr_save, 10);
ptr_save = NULL;
save[0] = '\0';
}
printf("Enter number of columns:\n");
if (fgets(save, sizeof(save), stdin) != NULL)
{
n_col = strtol(save, &ptr_save, 10);
ptr_save = NULL;
save[0] = '\0';
}
return EXIT_SUCCESS;
}
为了安全起见,我将指针*ptr_save
设置为NULL
,并在读完用户输入后将第一个元素设置为\0
并清除字符数组。用strtol()
处理它。但如果我没有将指针设置为NULL
并清除字符数组,代码是否同样安全? (对于那些想知道的人,稍后将在代码中检查用户输入。)
答案 0 :(得分:3)
由于您实际上并未使用endptr
(ptr_save
,我的意思是),没有必要将其设置为NULL
...并且您(正确地)通过{{1 } &ptr_save
,strtol()
并不关心您将strtol()
设置为ptr_save
。实际上,在给出NULL
未执行任何操作的示例中,您可以直接将ptr_save
传递给NULL
而不使用变量...但是,您应该使用{ {1}}正确并检查其后点,以验证strtol()
的结果。您还应该在每次ptr_save
通话之前清除strtol()
并在之后进行检查 - 这是检测范围错误和基本错误的唯一方法。
errno
不关心缓冲区中的strtol()
,领先或其他方式,如果在通话过程中出现问题,则无法保证您的领导fgets()
仍然存在。您应该检查NULL
的结果,看看它是否成功,而不是在缓冲区开头的NULL
上赌博。
此外,fgets()
返回NULL
...所占用的字节数,这不是表示基数为10的长字所需的最大字符数。
最后,在此函数的范围内,sizeof(long int)
在成功 long
后有效,ptr_save
在<<}后正确空终止后< em>成功 strtol()
...所以如果你检查结果,在任何一种情况下写空值都没有安全性。
答案 1 :(得分:0)
将指针设置为nil不会破坏它指向的内存。你只是'abadon'它。在这种情况下,尽管你的点指向你的char [],但是在堆栈中分配了内存,因此当你离开函数时它会被释放。
取决于您的需求可能没问题?!