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是我最喜欢的模块”出于好奇,code>查看它是否有效。它符合,但在执行时崩溃。关于如何修改代码使其工作,您有什么想法吗?您的程序中有很多错误。请考虑使用全局变量,并考虑使用<代码> 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;
}