【问题标题】:printf("%s",pch) VS. while(printf("%c"pch[i]))?printf("%s",pch) VS. while(printf("%c"pch[i]))?
【发布时间】:2013-04-29 13:35:02
【问题描述】:

我有一个字符串:“这是一个简单的字符串”

我的目标是找到(使用strstr)“简单”并将其替换为“样本”。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, char *argv[]){
    char *str;
    char *pch;

    int i=0;

    if((str=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }
    if((pch=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }
    str="This is a simple string ";
    pch=str;
    while(str[i]!='\0'){
        printf("%c",str[i]);
        i++;
    }
    printf(" -1break\n");

    while((*pch!='\0')){
        printf("%c",*pch);
        pch++;
    }
    printf(" -2break\n");

    printf("%s %d %d %d %d\n",str,strlen(str),sizeof(*str),BUFSIZ,(BUFSIZ-strlen(str)));/*OK*/

    if((pch=strstr(str,"simple"))!=NULL){
        printf("%s \n",pch);     **/*OK*/**         
        while((*pch!='\0')){
            printf("%c",*pch);
            pch++;
        }                           **/*SEG FAULT*/**
    strncpy(pch,"sample",6);
    printf("OK\n");
    }
    printf("%s %d\n",str,strlen(str));
    printf("\n");
    return 0;
}

输出:

$ ./strstr

This is a simple string  -1break

This is a simple string  -2break

This is a simple string  24 1 8192 8168

simple string  

Segmentation fault

$ 

问题:

不能用“sample”替换“simple”。

问题:

如果pch 正确指向“simple”的“s”,为什么strncpy 不能替换“sample”的6 个字母?

【问题讨论】:

  • BUFSIZ 的值是多少?此外,您通过malloc 将内存分配给strpch,然后很快重新分配内存,因此您在这里泄漏了内存。
  • -1。另一个类型的问题:char* var="hello world"; strcpy(var,"hello universe"); OR char* var="hello world"; var[5]=a;
  • anishane 这就是我试图理解 strcpy 和 var[5]=a 之间的区别是什么??

标签: c arrays segmentation-fault printf strstr


【解决方案1】:

总结您的str 指针应该指向一个读/写内存区域,例如分配有malloc/calloc/realloc 或静态字符数组(例如char str[50])的内存或char str[] = "simple string";

char *str = "simple string", str 这里指向一个文字字符串。并且文字字符串存储在只读内存区域中,因此您无法对其进行编辑

代码批评者:

1) 首先下面一行是错误的

str="This is a simple string ";

你已经为 str 分配了一个内存,然后你没有使用它,你已经更改了指针。指针现在指向文字字符串(常量字符串)而不是其原始内存区域(使用 malloc 分配)。应该是:

strcpy(str,"This is a simple string ");

同样的

pch = str;

pch 指向 str 的同一个字符串

pch=strstr(str,"simple")

pch 这里也指向一个文字字符串,因为str 是一个文字刺

2) 下面一行是错误的

strncpy(pch,"sample",6);

pch 指向文字字符串,复制到指向文字字符串的指针是未定义的行为,这会导致崩溃

代码已修复:

int main (int argc, char *argv[]){
    char *str;
    char *pch;

    int i=0;

    if((str=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }

    strcpy (str, "This is a simple string ");
    if((pch=strstr(str,"simple"))!=NULL) {
        strncpy(pch,"sample",6);
    }
    printf("%s\n", str);
}

【讨论】:

  • 非常感谢,我可以从中了解到“const *char”和“*char”不是一回事?现在更详细的问题:如果我的 str 通过 read(3) 接收到字符串,我还能替换 str 中的单词吗?
  • 作为总结,你的 str 指针应该指向一个读/写内存区域,比如分配有 malloc 的内存或静态字符数组,如 char str[50]char str[] = "simple string";
  • 但是char *str = "simple string", str 这里指向一个文字字符串。并且文字字符串存储在只读内存区域中,因此您无法对其进行编辑
【解决方案2】:

同意 MOHAMED 的回答。此外,由于您已经将“pch”移动到“\0”,即在strncpy之前的while循环中,导致了分段错误。 strncpy 现在写入超出文字字符串“这是一个简单字符串”的末尾,导致分段错误。正如其他人所指出的,您还通过将 str (在 malloc 之后)重新分配给文字字符串而导致内存泄漏。

【讨论】:

  • 当你发布它时我才意识到 pch++ 达到了'/0' 谢谢
猜你喜欢
  • 2019-12-12
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2017-01-17
  • 2015-01-05
  • 1970-01-01
相关资源
最近更新 更多