首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >意外字符串行为C++

意外字符串行为C++
EN

Stack Overflow用户
提问于 2022-01-08 18:36:35
回答 2查看 95关注 0票数 -2

我正在自学C++,正在阅读"C++速成班“一书,其中有以下练习:

3-2.向清单3-6中添加一个read_from和一个write_to函数。这些函数应酌情读或写到上或下。执行边界检查以防止缓冲区溢出。

它引用的清单3-6如下所示:

代码语言:javascript
复制
#include <cstdio>

int main(){

    char lower[] = "abc?e";
    char upper[] = "ABC?E";
    char* upper_ptr = upper;

    lower[3] = 'd';
    upper_ptr[3] = 'D';

    char letter_d = lower[3];
    char letter_D = upper_ptr[3];

    printf("lower: %s\nupper: %s\n", lower, upper);
}

我改写它的方式是:

代码语言:javascript
复制
char* write_to(char string[], int index, char replacement){
    if (sizeof(string) <= index){
        string[index] = replacement;
        return string;
    }
    return NULL;
};

char read_from(char string[], int index){
    if (sizeof(string) <= index){
        return string[index];
    }
    return NULL;
};

int main(){

    char lower[] = "abc?e";
    char upper[] = "ABC?E";
    char* upper_ptr = upper;

    lower[3] = 'd';
    upper_ptr[3] = 'D';

    char letter_d = lower[3];
    char letter_D = upper_ptr[3];

    printf("lower: %s\nupper: %s\n", lower, upper);

    char* changed_lower[] = {write_to(lower, 3, 's')};

    printf("changed lower: %s\nindex 3 of upper: %s\n",
        changed_lower, read_from(upper, 3));

该程序运行,但给我一些警告和错误的结果:

代码语言:javascript
复制
lower: abcde
upper: ABCDE
changed lower: 
index 3 of upper: (null)

我认为程序应该返回更像:

代码语言:javascript
复制
lower: abcde
upper: ABCDE
changed lower: abcse
index 3 of upper: D

我哪里出问题了?

编辑:我删除了警告,因为人们过于专注于这些,而不是真正的问题,那就是它没有给我正确的输出。

EN

回答 2

Stack Overflow用户

发布于 2022-01-08 18:55:45

有许多错误。

例如,这个函数声明

代码语言:javascript
复制
char* write_to(char string[], int index, char replacement){

等于

代码语言:javascript
复制
char* write_to(char *string, int index, char replacement){

由于隐式调整具有数组类型的参数为编译器指向数组元素类型的指针。

因此,在函数中,表达式

代码语言:javascript
复制
sizeof(string)

产生指针的大小,而不是传递数组的大小。

您需要使用标头sizeof中声明的标准C字符串函数strlen,而不是操作符<cstring>

另外,从这两个函数返回NULL也是没有意义的。

代码语言:javascript
复制
return NULL;

由于函数read_from的返回类型为char,所以不能使用带有函数返回值的转换说明符%s

代码语言:javascript
复制
printf("changed lower: %s\nindex 3 of upper: %s\n",
        changed_lower, read_from(upper, 3));

您需要使用转换说明符%c

变量changed_lower的声明为具有数组类型

代码语言:javascript
复制
char* changed_lower[] = {write_to(lower, 3, 's')};

也不太合理。您可能不会使用转换说明符%s输出它。至少,如果变量具有数组类型,则需要在调用changed_lower[0]时使用参数表达式printf

虽然最好只声明一个指针

代码语言:javascript
复制
char *changed_lower = write_to(lower, 3, 's');

这些函数可以通过以下方式声明和定义

代码语言:javascript
复制
#include <cstring>

char * write_to( char string[], size_t index, char replacement )
{
    if ( index < std::strlen( string ) )
    {
        string[index] = replacement;
    }

    return string;
}


char read_from( const char string[], size_t index )
{
    return index < std::strlen( string ) ? string[index] : '\0';
}

请注意函数声明后的空声明如下

代码语言:javascript
复制
char* write_to(char string[], int index, char replacement){
    //...
};
^^^

都是多余的,应该移除。

票数 2
EN

Stack Overflow用户

发布于 2022-01-08 18:49:49

代码语言:javascript
复制
void func1() {
    char str[] = "abcde";
    func2(str);
    ...
}

void func2(char str[]) {
    ...
}

如果是func1,则sizeof(str)的值等于6(5个字符+空字符)。

如果是func2,则sizeof(str)的值等于sizeof(char*),即平台上内存指针的大小(通常为4或8个字节,但理论上可以是任何其他值)。

调用func2(str)时,只有指向字符串开头的指针传递给函数,而不是整个字符串。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70635288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档