我有一个我正在处理的问题的简化版本。本质上,我需要读取一行输入并检查其中使用了哪些字符。
如果我有句台词:“乔伊喜欢面包”
输出将是:“abdeijklors”
输入>>“敏捷的棕色狐狸跳过懒惰的狗”
输出>>“abcdefghijklmnopqrstuvwxyz”(The Alphabet)
我应该可以将它加载到一个数组中-但这不起作用。
下面是我的代码的一个例子,只对字母表进行了简化。ASCII值的降低和提高仅仅是为了一个很好的例子。
#include "letters.h"
#include <ctype.h>
#include <stdio.h>
void letters_used(char *line) {
int c;
int table[26]={0};
int buff;
//Go through the line and set values to 1 in each alphabetic position
while (line) {
c = *line;
if (isalpha(c)) {
if isupper(c) {
c = tolower(c);
}
table[c-97]=1; //Lowering ASCII value for alphabetized order
}
line++;
}
//Walk through the array and print any true values
int i;
for (i=0;i<26;i++){
c = table[i];
if (c) {
c += 97 //Raising ASCII value back to normal
printf("%c", c);
}
}
printf("\n");
字符串
但是无论我做什么,数组都不会打印,因为数组的值仍然被设置为0。如果我手动设置它们,它工作得很好,但是当我把它扔到循环中的时候,我不能把值加载到数组中,它保持在0。我在这里错过了一些愚蠢的明显的东西吗?
3条答案
按热度按时间qqrboqgw1#
1.删除你没告诉我们的标题。
1.修复语法错误。
1.更喜欢
const
参数而不是文档,它不会改变。while(line)
不正确;您想使用while(*line)
来测试终止'\0'
。您的程序在此更改之前发生了段错误。1.打印循环使用了错误的变量
c + 'a'
,而它应该是i + 'a'
。否则你只会得到一堆“b”。1.对于迭代,优先使用
for
而不是while
循环。1.无条件地调用
tolower()
而不是有条件地调用isupper()
。这样代码就简单了一点,而且你消除了一个分支。我消除了变量c
,但也可以保留它。1.(不固定)更喜欢将算法与I/O分离。最干净的接口是返回一个动态分配的字符串(如果
line == NULL
,这也允许您返回NULL);或者让调用者传入一个合适的out参数。调用者然后打印字符串或任何需要的东西。字符串
和示例输出:
型
xytpbqjk2#
这段代码的工作原理:
字符串
它产生输出:
型
关键点是在打印循环中调用
printf()
时使用i
而不是c
。(在问题中,打印循环包含c = table[i];
和printf("%c", c + 97);
。)我还修改了while
循环以正确扫描输入,避免在多行中分割循环控制。代码在isalpha()
和tolower()
函数中使用字母之前将其转换为unsigned char
;这保护了系统上的代码,其中普通char
类型是有符号类型,并且用户键入的字符的代码范围为0x80..0xFF。注意,tolower()
可以无条件调用;它不会修改已经是小写的字母,也不会修改非字母。我使用'a'
而不是97
,因为它更清楚它在做什么。vawmfj5a3#
这里:
字符串
总是1或0。所以这里:
型
总是“a”或“b”。
那么,你想在这里得到什么呢?可能你是说
c = (char)(i + 97)
?