#include<stdio.h>
#include<stdlib.h>
int main()
{
char *userInput;
userInput = (char*)malloc(sizeof(userInput));
printf("Commands:\n");
printf("\ta name - adds given name to list\n");
printf("\tr name - removes given name from list\n");
printf("\tp - prints out list\n");
printf("\te - exits\n");
printf("\n\nEnter a command: ");
scanf("%s\n",userInput);
printf("\nThe user input was: %s\n", userInput);
return 0;
}
我编译代码“gcc -std = gnu99 -m32 -Wall -g -o namelist namelist.c” 每当我运行可执行文件时,都会显示所有第一个printf,并在输入时得到提示。每当我输入一个输入并按回车键时,在我输入另一个输入之前,我都没有得到下一个printf的提示。
答案 0 :(得分:1)
字符(char
)或字符集char*
)来自stdin
scanf
类似函数\n
(输入结果)键推)保留在缓冲区中。因此,在下一次输入之前,程序应该清除\n
以及输入缓冲区中可能存在的所有其他混乱(例如,在输入错误的数字后,例如12asw
- scanf
需要{{ 1}}并在缓冲区中留下12
。
请考虑以下示例并注意,我建议使用asw\n
:
clnInpBuf()
<强>更新强>
“命令处理器”的模板可以是:
#include <stdio.h>
void clnInpBuf()
{
char c;
while ((c = getchar()) != '\n' && c != EOF);
}
int main(void)
{
char str[10];
char ch;
scanf("%c", &ch);
fflush(stdin); // in some cases that works for input stream
// (but fflush is better to use only for output streams)
scanf("%9s", str);
clnInpBuf(); // this works always
printf("char was %c.\n", ch);
printf("string was %s.\n", str);
}
答案 1 :(得分:0)
只需取出
中的“\ n”即可SELECT Year , ID , Amount
FROM #Table T1
JOIN
(
SELECT MAX(Amount) Amount,Year
FROM #Table
GROUP BY Year
) A ON A.Year = T1.Year AND A.Amount = T1.Amount
答案 2 :(得分:0)
仔细阅读 scanf(3)。请注意,对于gcc -m32
,sizeof(userInput)
等于4(所有指针的大小相同;没有-m32
则为8)。因此,如果用户输入类似working
的内容(或任何四个字符或更多字符的输入,而不只是a
之类的一个字母),则表示您undefined behavior(因为buffer overflow })那真的是bad。您可能应该考虑使用getline(3)代替(或者甚至readline(3)),例如
char* userInput=NULL;
size_t sizeInput= 0;
printf("Commands:\n");
/// put your other printfs here, then
ssize_t lengthInput = getline(&userInput, &sizeInput, stdin);
if (lengthInput < 0 || userInput==NULL)
{ perror("input error"); exit(EXIT_NULL); };
现在您在userInput
中有完整的输入行(包括终止换行符),并且您知道其长度为lengthInput
。您可parse该行,可能使用sscanf(3)(提示:使用其返回计数,并考虑使用%n
)或仅使用其他技术(某些strcmp
或{{ 3}} ...)。完成后,您应该free(userInput)
。
请注意scanf
(或sscanf
)不为分析的数据分配任何内存,除非您使用%ms
(可能是POSIX特定的)。对于%s
,它总是期望一些固定长度的缓冲区,对于声明为char buf[64];
的数组缓冲区,您最好使用%63s
给出大小;顺便说一句,你应该总是测试scanf
的结果数。所以你可能会编码(在上面之后)
char nambuf[64];
if (sscanf(userInput, "a %63s", nambuf)==1) {
// use nambuf to add it
}
else if (sscanf(userInput, "r %63s", nambuf)==1) {
// use nambuf to remove it
}
(但上面有点傻,我们读取一个任意大小的行,但最多63个字节的进程nambuf
)。您可以使用scanf
之类的if (scanf("a %63s", nambuf)==1)
,而无需任何userInput
。
或者,您可以使用特定于Linux的%as
或更好的POSIX特定%ms
,如:
char* nameptr=NULL;
if (scanf("a %ms", &nameptr)==1) {
然后成功的scanf
将malloc
- 编辑并填充nameptr
,您应该稍后free(nameptr)
。如果您只想接受小写字母,请考虑使用if (scanf("a %m[a-z]", &nameptr)==1)
等编码...
答案 3 :(得分:0)
当userinput是指针时,此语句将分配4个字节的数据。 userInput =(char *)malloc(sizeof(userInput));
如上面的答案所指出的,当字符串大小超过3个字节时,这将导致缓冲区溢出。
我也会在读取字符串
时建议使用scangets上的fgets()示例代码 -
#include <stdio.h>
#include <stdlib.h>
int main() {
// your code goes here
char *userinput = (char *)malloc(100);
fgets(userinput,100,stdin);
printf("%s",userinput);
return 0;
}