C 使用指针手动复制字符串时出错

C 使用指针手动复制字符串时出错,c,string,pointers,compiler-errors,crash,C,String,Pointers,Compiler Errors,Crash,我创建这个项目是作为大学作业的一部分。目标是复制char*标语=“Comp10120是我最喜欢的模块”编码为新字符串。这是我的代码: #include <stdio.h> #include <stdlib.h> #include <ctype.h> void printStrings(); char *slogan = "Comp10120 is my favourite module"; char *p = slogan; char *slogan_co

我创建这个项目是作为大学作业的一部分。目标是复制
char*标语=“Comp10120是我最喜欢的模块”编码为新字符串。这是我的代码:

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

void printStrings();

char *slogan = "Comp10120 is my favourite module";
char *p = slogan;
char *slogan_copy = NULL;

int main ()
{   
    //Get size of original string
    int slogan_size = 0;
    while (*p++ != '\0')
        slogan_size++;

    // Dynamically allocate memory to copy of string
    slogan_copy = (char*) malloc ((slogan_size+1) * sizeof(char));
    //Place string terminator at end of copy string
    slogan_copy[slogan_size] = '\0';

    //Reset p pointer to start of string
    p = slogan;
    int offset = 0;

    while (*p != '\0')
    {
        //If the current element in the string is a consonant,
        //or as defined in the if statement,
        //if p is not a vowel and is between a and z or A and Z:
        if ((!(*p == 'a' || *p == 'e' || *p == 'i' || *p == 'o' || *p == 'u')) 
            && (((*p > 'a') && (*p < 'z')) || ((*p > 'A') && (*p < 'Z'))))
            p++;
        else
            //Copy element to slogan_copy and capitalise
            slogan_copy[offset++] = *p++;
            slogan_copy[offset] = toupper(slogan_copy[offset]);
    }

    //Place string terminator after last element copied.
    slogan_copy[offset] = '\0';

    printStrings();

    return 0;
}

void printStrings ()
{
    printf("Origianl String: %s\n",*slogan);
    printf("Modified String: %s",*slogan_copy);
}
我假设这是因为我试图对
标语
执行操作,就好像它只是一个规则的字符数组,而不是一个字符串指针。但是,我不知道如何修复这个错误


除此之外,我还尝试更改
char*标语=“Comp10120是我最喜欢的模块”
char标语[]=“Comp10120是我最喜欢的模块”查看它是否有效。它符合,但在执行时崩溃。关于如何修改代码使其工作,您有什么想法吗?

您的程序中有很多错误。请考虑使用全局变量,并考虑使用<代码> const <代码>,但它是一个非常好的起点,所以我已经测试了您的程序,它似乎与4个简单的修正:

1.删除全局环境中的
p
初始化

8: //char *p = slogan;
9: char *p;
  • main
    块内设置
    p

    int main() { p=口号; ... }

  • printf
    语句中的
    标语
    中删除astrix,因为它已经是指向字符数组的指针

    printf(“原始字符串:%s\n”,标语); printf(“修改后的字符串:%s”,标语\u副本)


  • 希望这对您有所帮助

    根据您在评论中的要求,这里是一个简化且正确的版本:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    int main()
    {
      const char *slogan = "Comp10120 is my favourite module";
    
      // Dynamically allocate memory to copy of string
      char *slogan_copy = malloc((strlen(slogan) + 1) * sizeof(char));
    
      //Reset p pointer to start of string
      const char *p = slogan;
      int offset = 0;
    
      while (*p != '\0')
      {
        //If the current element in the string is a consonant,
        //or as defined in the if statement,
        //if p is not a vowel and is between a and z or A and Z:
        char c = toupper(*p++);
        if (!isalpha(c) || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || )
          slogan_copy[offset++] = c;
      }
    
      //Place string terminator after last element copied.
      slogan_copy[offset] = '\0';
    
      printf("Origianl String: %s\n", slogan);
      printf("Modified String: %s\n", slogan_copy);
    
      return 0;
    }
    

    需要做一些改进

    1) 在函数
    printf
    format
    %s
    中,需要指向缓冲区的指针。无需取消对
    标语的引用
    标语的复制

    (二)

    上述方法行不通。它将使下一个字符位于上方而不是当前字符

    3) 在
    C
    语言中,不需要强制转换
    malloc

    4) 应该不惜一切代价避免全局变量。中断封装。 将变量作为参数传递,您将获得更大的灵活性

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    void printStrings (const char *format, const char *s);
    
    int main (void)
    {   
        char *slogan = "Comp10120 is my favourite module";
        char *p = slogan;
        char *slogan_copy;
        int offset = 0;
        int slogan_size = 0;
    
        //Get size of original string
    
        while (*p++ != '\0')
            slogan_size++;
    
        // Dynamically allocate memory to copy of string
    
        slogan_copy = malloc ((slogan_size+1) * sizeof(char));
    
        //Place string terminator at end of copy string
        slogan_copy[slogan_size] = '\0';
    
        //Reset p pointer to start of string
        p = slogan;
    
        while (*p != '\0')
        {
            //If the current element in the string is a consonant,
            //or as defined in the if statement,
            //if p is not a vowel and is between a and z or A and Z:
            if ((!(*p == 'a' || *p == 'e' || *p == 'i' || *p == 'o' || *p == 'u')) 
                && (((*p > 'a') && (*p < 'z')) || ((*p > 'A') && (*p < 'Z'))))
                p++;
            else{
                //Copy element to slogan_copy and capitalise
                slogan_copy[offset] = *p;
                slogan_copy[offset] = toupper(slogan_copy[offset]);
    
                *p++;
                offset++;
            }
        }
    
        //Place string terminator after last element copied.
        slogan_copy[offset] = '\0';
    
        printStrings("Origianl String: %s\n", slogan);
        printStrings("Modified String: %s\n", slogan_copy);
    
        return 0;
    }
    
    void printStrings (const char *format, const char *s)
    {
        printf(format,s);
    }
    

    您的代码缩进不正确:
    else
    分支有2条语句,但它们没有包装在带有
    {
    }
    的块中,因此只有第一条语句有条件地执行,而第二条语句始终执行,从而导致与大写特性相关的意外行为

    此外,大写字母不会应用于正确的偏移量,因为
    offset
    过早增加,大写元音也会被删除

    编码风格的合理规则是,除了最简单的语句外,所有复合语句都要使用大括号。以这种方式重写测试:

        int c = toupper((unsigned char)*p++);
        if (!isalpha(c) || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
            //Copy and capitalise element to slogan_copy
            slogan_copy[offset++] = c;
        }
    
    代码中还有其他问题,例如:为
    printf
    参数传递不正确的数据,以及无正当理由使用全局变量

    以下是一个改进的版本:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    int main() {   
        const char *slogan = "Comp10120 is my favourite module";
        char *slogan_copy = NULL;
    
        //Get size of original string
        int slogan_size = 0;
        while (slogan[slogan_size] != '\0')
            slogan_size++;
    
        // Dynamically allocate memory to copy of string
        slogan_copy = malloc(slogan_size + 1);
    
        //Reset p pointer to start of string
        const char *p = slogan;
        int offset = 0;
    
        while (*p != '\0') {
            int c = toupper((unsigned char)*p++);
            if (!isalpha(c) || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
                //Copy and capitalise element to slogan_copy
                slogan_copy[offset++] = c;
            }
        }
    
        //Place string terminator after last element copied.
        slogan_copy[offset] = '\0';
    
        printf("Original string: %s\n", slogan);
        printf("Modified string: %s\n", slogan_copy);
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    int main(){
    const char*标语=“Comp10120是我最喜欢的模块”;
    char*lamposon\u copy=NULL;
    //获取原始字符串的大小
    int\u size=0;
    同时(标语[标语大小]!='\0')
    标语_size++;
    //动态分配内存以复制字符串
    标语副本=malloc(标语尺寸+1);
    //将p指针重置为字符串的开头
    const char*p=标语;
    整数偏移=0;
    而(*p!='\0'){
    int c=toupper((无符号字符)*p++);
    如果(!isalpha(c)| c='A'| c='E'| c='I'| c='O'| c='U'){
    //将元素复制并大写,以便于复制
    标语_拷贝[offset++]=c;
    }
    }
    //将字符串终止符放在复制的最后一个元素之后。
    标语_copy[offset]='\0';
    printf(“原始字符串:%s\n”,标语);
    printf(“修改的字符串:%s\n”,标语\u副本);
    返回0;
    }
    
    printf(“原始字符串:%s\n”,*标语)
    当函数需要指针时,您正在传递一个
    char
    。应该是:
    printf(“原始字符串:%s\n”,标语)并放置
    char*p=标语
    main
    的开头,然后它将编译。但无论如何,你的代码非常复杂。你滥用全局变量是有问题的。而且,
    char*slamon=..
    应该是
    const char*slamon=..
    ,意思是
    char*p=slamon应该是
    const char*p=标语
    @MichaelWalz如果你有时间,你能建议一种方法让它稍微简单一点吗?我还在努力学习。我怀疑你的程序是否有效。它打印大写字母吗?有一个逻辑缺陷阻止了这一点。它没有回答最初的问题,但它为调试逻辑提供了一个更好的起点
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    void printStrings (const char *format, const char *s);
    
    int main (void)
    {   
        char *slogan = "Comp10120 is my favourite module";
        char *p = slogan;
        char *slogan_copy;
        int offset = 0;
        int slogan_size = 0;
    
        //Get size of original string
    
        while (*p++ != '\0')
            slogan_size++;
    
        // Dynamically allocate memory to copy of string
    
        slogan_copy = malloc ((slogan_size+1) * sizeof(char));
    
        //Place string terminator at end of copy string
        slogan_copy[slogan_size] = '\0';
    
        //Reset p pointer to start of string
        p = slogan;
    
        while (*p != '\0')
        {
            //If the current element in the string is a consonant,
            //or as defined in the if statement,
            //if p is not a vowel and is between a and z or A and Z:
            if ((!(*p == 'a' || *p == 'e' || *p == 'i' || *p == 'o' || *p == 'u')) 
                && (((*p > 'a') && (*p < 'z')) || ((*p > 'A') && (*p < 'Z'))))
                p++;
            else{
                //Copy element to slogan_copy and capitalise
                slogan_copy[offset] = *p;
                slogan_copy[offset] = toupper(slogan_copy[offset]);
    
                *p++;
                offset++;
            }
        }
    
        //Place string terminator after last element copied.
        slogan_copy[offset] = '\0';
    
        printStrings("Origianl String: %s\n", slogan);
        printStrings("Modified String: %s\n", slogan_copy);
    
        return 0;
    }
    
    void printStrings (const char *format, const char *s)
    {
        printf(format,s);
    }
    
    Origianl String: Comp10120 is my favourite module                                                                                            
    Modified String: O10120 I  AOUIE OUE  
    
        int c = toupper((unsigned char)*p++);
        if (!isalpha(c) || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
            //Copy and capitalise element to slogan_copy
            slogan_copy[offset++] = c;
        }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    int main() {   
        const char *slogan = "Comp10120 is my favourite module";
        char *slogan_copy = NULL;
    
        //Get size of original string
        int slogan_size = 0;
        while (slogan[slogan_size] != '\0')
            slogan_size++;
    
        // Dynamically allocate memory to copy of string
        slogan_copy = malloc(slogan_size + 1);
    
        //Reset p pointer to start of string
        const char *p = slogan;
        int offset = 0;
    
        while (*p != '\0') {
            int c = toupper((unsigned char)*p++);
            if (!isalpha(c) || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
                //Copy and capitalise element to slogan_copy
                slogan_copy[offset++] = c;
            }
        }
    
        //Place string terminator after last element copied.
        slogan_copy[offset] = '\0';
    
        printf("Original string: %s\n", slogan);
        printf("Modified string: %s\n", slogan_copy);
    
        return 0;
    }