我写了一个简单的程序,它在一个空格后返回值:例如输入“alababa 4”给出返回4,在没有空格然后它是0.但是现在我想扫描那个字符串,它只是没有工作,我不知道我在哪里弄错了。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(){
//char * string="alababa 4" - it worked that way
char * string;
scanf("%c", &string);
int dlugosc=strlen(string);
for(int i=0;i<=dlugosc-1; i++)
{
char temp;
temp=string[i];
char str2[] = " ";
if(temp==' ')
{
char * pZnak = strpbrk( string, str2 );
printf( "%s \n", pZnak );
return pZnak[1]-48;
}
}
return 0;
}
第二个问题,为什么回报比它应该大48?
答案 0 :(得分:2)
您创建了一个指向char的指针,但没有为其分配内存。最简单的方法是创建一个具有固定大小的char数组。
在scanf
%c
表示读取单个字符,使用%s
读取字符串,但scanf()
仅读取空格符号,而不读取&#39; \ n&#39 ;。当你输入&#34; alababa 4&#34;它只会读取alababa。您可以使用gets()
或fgets()
来读取整个字符串。此外,变量string
已经是您不需要在那里使用&
的指针。正确的语法是:scanf("%s", string);
但正如我所说,它只会读取第一个单词。
您计划中的pZnak[0]
拥有“空格”。并且pZnak[1]
拥有&#39; 4&#39;。 &#39; 4&#39;的ASCII代码是52。
这是从键盘读取字符串并在屏幕上的空格符号后打印所有内容的程序。
#include <stdio.h> // for printf() and gets()
#include <string.h> // for strpbrk()
int main(void) {
char string[80]; // It can contain a string of 79 symbols + '/0'
char *checkStr = " ";
gets(string);
char *ptr = strpbrk(string, checkStr);
printf("%s\n", ptr);
return 0;
}
答案 1 :(得分:0)
这里的问题非常不同。首先,您传递了一个指针变量的地址,该变量没有指向scanf
可以存储输入数据的某个有效内存位置。您已在代码中调用未定义的行为。
你想要的东西可以使用sscanf
完成,它基本上在缓冲区上使用scanf
。 sscanf(buf,"%s%d",str,&num)
。但是如果失败则不会返回值2
。但是这个解决方案并不是那么好 - scanf
类对于格式化输入很有用(通过错误检查机智scanf
进行大量麻烦)。更好的方法是使用strtok
解析输入字符串。如果你有一个tken然后就完成了。没有提供数字或数字。如果返回2令牌,则使用strtol
获取第二个令牌的整数值。
如果您知道只有1位数字,那么您可以进行简单的循环 - 并检查您在前一段中找到的第二个标记。如果你得到一个数字并且它是唯一的数字,那么你可以确定这是你必须解析的唯一数字。您只需将其存储在int
变量中即可。
插图代码:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#define MAXLEN 100
int main(){
char s[MAXLEN+1];
int numParsed = 0;
int iter = 1;
if(fgets(s,MAXLEN+1,stdin)!=NULL){
char * str= strtok(s," ");
while(str!=NULL){
str = strtok(NULL," ");
if(iter && str!=NULL){
iter = 0;
char *t;
errno = 0;
long n = strtol(str, &t, 10);
if ((errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))|| (errno != 0 && n == 0)) {
perror("strtol");
exit(EXIT_FAILURE);
}
if (t == str) {
fprintf(stderr, "No digits were found\n");
exit(EXIT_FAILURE);
}
if ( n >= INT_MIN && n <= INT_MAX)
{
numParsed = n;
}
else{
fprintf(stderr, "Too big/small a number\n");
exit(EXIT_FAILURE);
}
}else if(iter == 0 && str){
fprintf(stderr, "%s\n","Input=> String[SPACE]Num" );
exit(EXIT_FAILURE);
}
}
if(iter == 0)
printf("[%d]\n",numParsed );
else
printf("%s\n", "Format: String[SPACE]int");
}
return 0;
}
答案 2 :(得分:0)
scanf("%c",...)
读取单个字符,而不是0个字符的字符序列。因此,char * string;scanf("%c", &string);
在两个方面是错误的:(1)它将字符读入指向字符的指针,(2)它不按预期读取字符串而是单个字符。如果你写char*string;scanf("%s",string)
,那么你将字符串读入无效内存(因为指针string
没有指向有效分配的内存),这是未定义的行为。
你必须写char string[20]; scanf("%19s",string)
然后,您可以根据需要解析输入字符串。 BTW:你的解析器似乎有点复杂;一个简单的if (scanf("%*s%d",&num)==1) { ...
可以胜任这项工作; *
表示%s
的输入应解析但不存储在某处,%d
在跳过其间的所有空格后读取数字部分。