请参阅下面的代码。用户应该输入一个句子,代码应该返回句子的首字母缩略词。
但是,当我分配* str并将N定义为1时。
"三个字母的首字母缩略词" >>应该是>> " T"
实时,"三个字母的首字母缩略词" >>是>> " TLA"
这没有意义。 请解释为什么会发生这种情况。
#include <stdio.h>
#include <stdlib.h>
#define N 1
#define M 35
char *acronyms (char *st, char *sentence);
int main()
{
char *str=(char*)(malloc(N*sizeof(char)));
char *sen=(char*)(malloc(M*sizeof(char)));
printf("enter... ");
gets(sen);
puts(acronyms(str, sen));
free(str);
free(sen);
return 0;
}
char *acronyms (char *st, char *sentence)
{
char *p = st;
char *q = sentence;
if (*q !=' ') {
*p =*q;
p++;
}
while (*(q+1)) {
if (*q==' ' && *(q+1)!= ' ') {
*p = *(q+1);
p++;
}
q++;
}
*p='\0';
return st;
}
答案 0 :(得分:1)
首先,您不应该使用gets()
。为什么??检查this。
您只将1
字节的内存分配给str
:
char *str=(char*)(malloc(N*sizeof(char)));
并且在函数acronyms()
中,您正在编写超出分配的内存。这是undefined behavior。
要获得输入句子的首字母缩写词,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define STR_LEN 100
char *acronyms (char *pstr, char *str_acronym);
int main(void) {
char input_str[STR_LEN];
char *sen = NULL;
printf ("Enter:\n");
fgets (input_str, STR_LEN, stdin);
sen = malloc (strlen(input_str) + 1);
if (sen == NULL) {
perror ("Failed to allocate memory");
return -1;
}
puts (acronyms(input_str, sen));
free(sen);
return 0;
}
char * acronyms(char *pstr, char *str_acronym)
{
int count = 0, add = 1;
for (int i = 0; pstr[i] != '\0'; i++) {
if (isspace(pstr[i])) {
add = 1;
continue;
}
if (add) {
str_acronym[count] = pstr[i];
count++;
add = 0;
}
}
str_acronym[count] = '\0';
return str_acronym;
}
答案 1 :(得分:1)
代码中存在一些问题:
1)仅为字符串str
分配一个字节:
#define N 1
char *str=(char*)(malloc(N*sizeof(char)));
2)使用gets(sen)
代替fgets(sen,M+1,stdin);
3)char *acronyms (char *st, char *sentence)
有很多问题的逻辑。无法识别字符串的结尾,' '
可能存在也可能不存在:
if (*q !=' ') {
*p =*q;
p++;
}
答案 2 :(得分:1)
乍一看这看起来似乎并不令人满意,但是一旦你理解了这5个概念所指出的基本原则(每个概念都有例子),这个和其他类似的任务看起来会简单得多。
做你正在尝试的事情的必要步骤:
1)了解控制台用户输入技术( Good example here )
2)理解字符串的定义( Good definition,explanation here 。)
3)了解[c][m]alloc(...)
( Good discussion here... ...)的使用情况
3a)......以及何时使用它。或不。 ( heap vs. stack memory )
4)理解字符串解析技术。 ( ex 1 , ex 2 , ex 3 )
5)了解合法但不明智的技巧,例如使用 gets 或 in general 。
这些通常是适用的技术,对包括用户输入和字符串操作在内的许多任务非常有用,但对于引用优秀的C书来提供基础知识的必要基础并不是一个很好的替代。
答案 3 :(得分:0)
未定义行为世界中的惠康!当您使用数组中的数据时,任何事情都可能发生包括预期结果。这就是这里发生的事情:为str分配1个单字节,并写入5 {'h', 'a, 'n', 'd', '\0'}
。 [联合国]幸运的是,在较低的级别,您似乎只会覆盖未使用的内存,并实际获得结果。
就像它是UB一样,你不能依赖它,并且在不同的环境中编译的相同源可能是SEGFAULT或者没有打印任何完全相同的输入。
正如你在评论don't use gets