CS50:pset2/首字母:-I';我有一些代码可以工作,但我觉得我在设置数组大小方面走了一条捷径
因此,我一直在研究CS50中首字母缩写问题的“不太舒服”版本,在开始编写非常详细的代码后,我设法将其简化为:CS50:pset2/首字母:-I';我有一些代码可以工作,但我觉得我在设置数组大小方面走了一条捷径,c,arrays,cs50,C,Arrays,Cs50,因此,我一直在研究CS50中首字母缩写问题的“不太舒服”版本,在开始编写非常详细的代码后,我设法将其简化为: #include <cs50.h> #include <ctype.h> #include <stdio.h> #include <string.h> int c = 0; int main(void) { string name = get_string(); int n = strlen(name); ch
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int c = 0;
int main(void)
{
string name = get_string();
int n = strlen(name);
char initials[10];
// first letter is always going to be the first initial
initials[0] = name[0];
// count through letters looking for spaces + add the first letter after a
// space to the initials array
for (int j = 0; j < n; j++)
{
if (name[j] == 32)
{
c += 1;
initials[c] += name[j+1];
}
}
// print out initials
for (int k = 0; k <= c; k++)
{
printf("%c", toupper(initials[k]));
}
printf("\n");
}
#包括
#包括
#包括
#包括
int c=0;
内部主(空)
{
string name=get_string();
int n=strlen(名称);
字符首字母[10];
//第一个字母总是第一个字母
姓名首字母[0]=姓名[0];
//通过字母进行计数,查找空格+在空格后添加第一个字母
//将空格添加到初始值数组
对于(int j=0;j 对于(int k=0;k首先,请记住,执行速度通常比内存使用更有价值。如果首先查找空间,然后分配内存,则必须在数组中迭代两次。这是以执行速度为代价的内存使用优化。因此,只分配一个“足够大”的数组,比如说100个字符,并保留您拥有的代码
然后我想将数组[spaces+1]设为如果有2个空格,那么将有3个首字母
请记住,C字符串是以null结尾的,因此您也需要为null结尾符分配空间,spaces+1+1
当我上传代码进行检查时,仅使用此“for”循环编译代码会返回一个失败(尽管它编译起来没有问题)。即使我不使用任何“for”循环输出,但它存在的事实也会导致此错误
什么错误?编译还是不编译,你的文本是矛盾的
确保将空格
初始化为零
作为旁注,切勿在C代码中使用“幻数”。如果(name[i]==32)
,32对于无法通过内存引用ASCII表的任何人来说都是胡言乱语。此外,对于具有其他可能没有相同索引号的符号表的系统,它是不可移植的。请改为编写:
if (name[i] == ' ')
在我看来,满足这种情况的一个好方法是库函数snprintf
使用的方法:它要求您传入要填充的字符串以及该字符串的大小。In确保字符串不会被覆盖,并且字符串以零结尾
如果字符串足够大,函数将返回写入字符串的字符长度。您现在可以执行以下两种操作之一:猜测合理的缓冲区大小,并接受字符串偶尔会被缩短。或者使用零长度调用函数,使用返回值分配一个字符缓冲区,然后用第二个电话
将此方法应用于您的姓名首字母问题:
int initials(char *ini, int max, const char *str)
{
int prev = ' '; // pretend there's a space before the string
int n = 0; // actual number of initials
while (*str) {
if (prev == ' ' && *str != ' ') {
if (n + 1 < max) ini[n] = *str;
n++;
}
prev = *str++;
}
if (n < max) {
ini[n] = '\0';
} else if (max > 0) {
ini[max] = '\0';
}
return n;
}
或两步动态大小方法:
char *name = "Theodore Quick Brown Fox";
char ini[4];
initials(ini, sizeof(ini), name);
puts(ini); // prints "TQB", "F" is truncated
char *name = "Theodore Quick Brown Fox";
int n;
n = initials(NULL, 0, name);
char ini[n + 1];
initials(ini, sizeof(ini), name);
puts(ini); // prints "TQBF"
(请注意,initals
的此实现将忽略多个空格和字符串末尾或开头的空格。在这种情况下,先行查找函数将插入空格。)您知道您的initials
数组不能比名称本身大;最多不能超过名称本身的一半(其他每个字符都是一个空格)。因此请将其用作大小。最简单的方法是使用可变长度数组:
size_t n = strlen( name ); // strlen returns a size_t type, not int
char initials[n/2+1]; // n/2+1 is not a *constant expression*, so this is
// a variable-length array.
memset( initials, 0, n + 1 ); // since initials is a VLA, we can't use an initializer
// in the declaration.
唯一的问题是,VLA支持可能不确定-VLA是在C99中引入的,但在C2011中是可选的
或者,您可以使用动态分配的缓冲区:
#include <stdlib.h>
...
size_t n = strlen( name );
char *initials = calloc( n/2+1, sizeof *initials ); // calloc initializes memory to 0
/**
* code to find and display initials
*/
free( initials ); // release memory before you exit your program.
或者使用isspace
library函数(对于空格、制表符、换行符等将返回true):
#包括
...
if(isspace(name[j]))
你为什么还要存储呢?只需将它打印出来就行了……否则,我打赌,计算出元素的数量,然后使用VLA。char*initials=malloc(spaces+1);
就像你的数组一样使用,但在使用完后调用free(initials);
char initials[spaces+1]
您得到编译错误还是运行时错误?如果您有一行包含“john q doe
”,则有2个空格,但有3个单词需要转换为首字母,因此您需要一个大小为4的数组来允许终端空字节-即空格数加2。您应该使用'
来表示空格,而不是32
。
#include <stdlib.h>
...
size_t n = strlen( name );
char *initials = calloc( n/2+1, sizeof *initials ); // calloc initializes memory to 0
/**
* code to find and display initials
*/
free( initials ); // release memory before you exit your program.
if ( name[j] == ' ' )
#include <ctype.h>
...
if ( isspace( name[j] ) )