我是C编程新手。现在我正在学习字符串和指针 作为初学者,我发现很难找到错误。我编写了一个动态分配字符串的代码,并使用函数打印字符串。代码如下所示。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void fun (char *);
int main()
{
int n;
char *s = NULL;
printf("enter the length of the string\n");
scanf("%d",&n);
s = (char*)malloc(n * sizeof(char));
printf("enter the string\n");
fgets(s, 20, stdin);
printf("string before passing is %s\n",s);
fun(s);
return 0;
}
void fun( char *p)
{
char *d;
d = p;
printf("string after passing is%s\n",d);
}
编译时没有错误消息。但是代码并没有采用字符串 谁能帮助我找到错误。
答案 0 :(得分:4)
您的代码中有五个主要错误。
scanf
不会&#34;消费&#34;点击 ENTER 时生成的换行符,因此您需要getchar
来跟踪它以处理此意外行为。malloc
的结果。此功能可能会失败。fgets
应使用n
来确定要从用户处获取的最大数据量,否则您将通过溢出缓冲区来生成细分错误。fgets
结果的字符串以换行符结束,在典型情况下为NULL终止字符。您可以使用strtok
替换带有NULL字符的尾部换行符,以避免意外行为。free
使用malloc
创建的内存。这会导致内存泄漏。 编辑:Matt McNabb提供了另一种方法来处理FIX1中未消耗的\n
,我认为这种方法比我的方法更清晰。
解决方案发布在下方。
代码清单
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void fun (char *);
int main() {
int n;
char *s = NULL;
printf("enter the length of the string\n");
scanf("%d",&n);
(void)getchar(); // FIX1
s = (char*)malloc(n * sizeof(char));
if (s == NULL) { // FIX2
printf("malloc error; aborting\n");
return 1;
}
printf("enter the string\n");
fgets(s, n, stdin); // FIX3
strtok(s, "\n"); // FIX4
printf("string before passing is %s\n",s);
fun(s);
free(s); // FIX5
return 0;
}
void fun(char *p) {
char *d;
d = p;
printf("string after passing is %s\n",d);
}
示例运行
enter the length of the string
10
enter the string
This is a test for overflows.
string before passing is This is a
string after passing is This is a
答案 1 :(得分:1)
scanf("%d",&n);
输入数字并按ENTER后,此scanf
行所采用的数字,但新行字符仍在缓冲区中。下一个fgets
行只占用新行。
解决问题的一种简单方法是:
scanf("%d",&n);
getchar(); //consume the new line
答案 2 :(得分:1)
当您编写scanf("%d",&n);
时,它会从流中提取整数。它不会丢弃剩余的线。因此,如果您键入一个数字并按下Enter键,则换行符将保留在流中。
所以当你fgets
时,它会读取该行的其余部分,这是空白的。
要解决此问题,您需要阅读最后一行。一种方法是:
int ch;
while ( (ch == getchar()) != '\n' && ch != EOF ) { }
然后你可以继续做:
fgets(s, n, stdin); // n, not 20
另外,你应该检查malloc的结果,例如
s = malloc(n);
if ( s == NULL )
return 0; // or some other error handling
自1989年以来,Castoc malloc一直是a mistake,但是你是否想要包括sizeof(char)
是一个风格问题,因为sizeof(char)
总是1
。< / p>
要完成,您还可以检查fgets
的结果,例如,如果您的输入已关闭,那么您将输出垃圾。
答案 3 :(得分:1)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void fun (char *);
int main()
{
int n;
char *s = NULL;
char ch;
/* Taking String length from the User */
printf("enter the length of the string\n");
scanf("%d",&n);
/* Allocating Memory */
s = (char*)malloc(n * sizeof(char));
/* Checking for memory allocation */
if (s == NULL)
{
printf("\n Error in allocating memory \n");
exit(0);
}
/* Flush standard inputs */
while ((ch = fgetc(stdin)) != EOF && ch != '\n')
{
}
printf("enter the string\n");
fgets(s, n+1, stdin);
printf("string before passing is %s\n",s);
fun(s);
/* Need to free the allocated memory */
free(s);
return 0;
}
void fun( char *p)
{
char *d;
d = p;
printf("string after passing is %s \n",d);
}
答案 4 :(得分:0)
简而言之,fgets从缓冲区读取并且缓冲区已经满了。解决方法是在阅读
之前不要使用fgets或flush bufferprintf("enter the string\n");
fflush(stdin);
fgets(s, 20, stdin);
UPD
所以如果stdin没有定义fflush,那么就像上面提到的Matt McNabb那样冲洗它
while ((ch = getchar()) != '\n' && ch != EOF);