C 为什么不是';我的removeString函数不能删除字符吗?

C 为什么不是';我的removeString函数不能删除字符吗?,c,arrays,string,C,Arrays,String,我正在做一本书中的练习,除了printf和scanf之外,我不允许使用任何库函数 我写了一个程序,它接受字符串。然后可以输入要从字符串中删除的字符数。然后选择执行此操作的索引 我的尝试是循环遍历我想保留在函数末尾的字符,然后用我想丢失的函数替换它们 出于某种原因,它的做法恰恰相反 如果我输入字符串:“错误的儿子” 然后选择删除6个字符并从数组的第4个索引开始 我应该得到:“儿子” 相反,我得到的是“wro” 我已经用头撞了4个小时了 你能告诉我哪里出了问题吗 #include <stdio

我正在做一本书中的练习,除了
printf
scanf
之外,我不允许使用任何库函数

我写了一个程序,它接受字符串。然后可以输入要从字符串中删除的字符数。然后选择执行此操作的索引

我的尝试是循环遍历我想保留在函数末尾的字符,然后用我想丢失的函数替换它们

出于某种原因,它的做法恰恰相反

如果我输入字符串:
“错误的儿子”
然后选择删除6个字符并从数组的第4个索引开始

我应该得到:
“儿子”

相反,我得到的是
“wro”

我已经用头撞了4个小时了

你能告诉我哪里出了问题吗

#include <stdio.h>

void removeString(char source[], int start, int count);
int stringLength(const char string[]);

    int main(void)
    {
        int start, count;
        char source[20]; 

        printf("What's your string?\n");
        scanf("%[^\n]s", source);

        printf("How many characters do you want to remove?\n");
        scanf("%i", &count);

        // Choose which index to start deletion from
        printf("Where are we starting from?\n");
        scanf("%i", &start);

        // Call function to remove characters from string
        removeString(source, start, count);

        // print out result, stored in source
        printf("Here's the result: %s\n", source);

        return 0;
    }

    void removeString(char source[], int start, int count)
    {
        int i, j;

        // Find length of string
        int length = stringLength(source);


        //loop through the last few characters that we DO want to keep until we hit the end of the string 
        for(i = (start+count); i <= length; i++)
        {
            //loop backwards through the string, from the first of the ones we want to keep, stop at the 'start' of the index
            for(j = (start+count)-1; j <= start; j--)
            {
                // assign 'i' which is the last few characters we want to keep and put them in the place of the characters we want to delete
                source[j] = source[i];
            }
        }

        // assign a null character to end the string once we've finished modifying
        source[count + 1] = '\0';
    }

    int stringLength(const char string[])
    {
        int count =0;

        while(string[count] != '\0')
            count++;

        return count;
    }
#包括
无效重新投资(字符源[],整数开始,整数计数);
int stringLength(const char string[]);
内部主(空)
{
int开始,计数;
字符源[20];
printf(“您的字符串是什么?\n”);
scanf(“%[^\n]s”,来源);
printf(“要删除多少个字符?\n”);
scanf(“%i”、&count);
//选择从哪个索引开始删除
printf(“我们从哪里开始?\n”);
scanf(“%i”,开始(&start));
//调用函数从字符串中删除字符
重新投资(来源、开始、计数);
//打印输出结果,存储在源文件中
printf(“这是结果:%s\n”,来源);
返回0;
}
无效重新投资(字符源[],整数开始,整数计数)
{
int i,j;
//查找字符串的长度
int length=stringLength(源);
//循环最后几个我们想要保留的字符,直到到达字符串的末尾

对于(i=(start+count);i您只需要一个for循环就可以实现这一点。假设我们可以成功避免在字符串末尾运行,您可以编写如下内容:

for(i = start; i < start + count && i < length; i++) {
   source[i] = source[i+count];
}
for(i=start;i

你只需要在正确的位置设置一个空字符。但是,这不是计数。也许是在长度-CONT-1(或者考虑Ststart + Cube),因为你正在删除“计数”字符。

你能告诉我哪里出了问题吗

#include <stdio.h>

void removeString(char source[], int start, int count);
int stringLength(const char string[]);

    int main(void)
    {
        int start, count;
        char source[20]; 

        printf("What's your string?\n");
        scanf("%[^\n]s", source);

        printf("How many characters do you want to remove?\n");
        scanf("%i", &count);

        // Choose which index to start deletion from
        printf("Where are we starting from?\n");
        scanf("%i", &start);

        // Call function to remove characters from string
        removeString(source, start, count);

        // print out result, stored in source
        printf("Here's the result: %s\n", source);

        return 0;
    }

    void removeString(char source[], int start, int count)
    {
        int i, j;

        // Find length of string
        int length = stringLength(source);


        //loop through the last few characters that we DO want to keep until we hit the end of the string 
        for(i = (start+count); i <= length; i++)
        {
            //loop backwards through the string, from the first of the ones we want to keep, stop at the 'start' of the index
            for(j = (start+count)-1; j <= start; j--)
            {
                // assign 'i' which is the last few characters we want to keep and put them in the place of the characters we want to delete
                source[j] = source[i];
            }
        }

        // assign a null character to end the string once we've finished modifying
        source[count + 1] = '\0';
    }

    int stringLength(const char string[])
    {
        int count =0;

        while(string[count] != '\0')
            count++;

        return count;
    }
在你的索引中

我不会发布一个简单的解决方案,我会尽力让你明白你错在哪里

for(i = (start+count); i <= length; i++)
它说从9开始(例如输入),然后减小
j
直到小于或等于4,这没有意义,你的意思是写:

j>=开始


现在拿起一张纸,写下你的输入和你的指针,请:

start = 4
count = 6
length = 13

       start    start+count
         |           |
         V           V
|t|h|e| |w|r|o|n|g| |s|o|n|
 0 1 2 3 4 5 6 7 8 9 101112
现在运行你的算法

您将获得第i个字符并覆盖所有第j个字符,这就是为什么在应用我的修复后,您最终会得到“nnn”,对吗

因此,您要做的是一直到
开始
加上您已经覆盖的内容,并且不应再次覆盖

因此,请更改以下内容:

j>=开始

您应该得到以下输出:

C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
What's your string?
the wrong son
How many characters do you want to remove?
6
Where are we starting from?
4
Here's the result: the son
如果不是这样的话,告诉我发布整个固定代码


编辑:

我对“\0”的追加错误

不,这是正确的(至少在回答中提出了所有修复之后)。让我们用以下代码检查一下:

printf("source = %s\n", source);
printf("count = %d\n", count);
printf("source[count] = %c\n", source[count]);
printf("source[count + 1] = %c\n", source[count + 1]);
source[count + 1] = '\0';
其中:

source = the sonnnnson
count = 6
source[count] = n
source[count + 1] = n

因此,
count+1
等于7,这是字符串中的第二个'n',这正是我们要放置空终止符的位置。

您需要修改循环-

for(i=start, j=(start+count) ; j<=length; i++, j++){
    source[i]=source[j];    
}
// assign a null character to end the string once we've finished modifying

source[strlen(source)-1]='\0';   // include string.h for strlen()

for(i=start,j=(start+count);j考虑使用fgets读取输入,使用sscanf解析整数。检查sscanf(或scanf)的返回以查看是否存在问题。在
removesting
中,可以使用一对指针迭代字符串

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

void removeString(char source[], int start, int count);
int stringLength(const char string[]);

int main(void)
{
    int start, count;
    int result = 0;
    char source[120];
    char input[120];

    printf("What's your string?\n");
    if ( ( fgets( source, sizeof ( source), stdin)) == NULL) {
        printf ( "could not get input\n");
        return 1;
    }
    source[strcspn ( source, "\n")] = '\0';//remove newline

    do {
        printf("How many characters do you want to remove?\n");
        if ( ( fgets( input, sizeof ( input), stdin)) == NULL) {
            printf ( "could not get input\n");
            return 1;
        }
        result = sscanf(input, "%d", &count);
    } while ( result != 1);//loop on bad input

    do {
        printf("Where are we starting from?\n");
        if ( ( fgets( input, sizeof ( input), stdin)) == NULL) {
            printf ( "could not get input\n");
            return 1;
        }
        result = sscanf(input, "%d", &start);
    } while ( result != 1);//loop on bad input

    removeString(source, start, count);

    printf("Here's the result: %s\n", source);
    return 0;
}

void removeString(char source[], int start, int count)
{
    char *to = NULL, *from =NULL;

    int length = stringLength(source);

    if ( start > length) {//very short source
        return;
    }

    if ( start + count > length) {//source still too short
        source[start] = '\0';//truncate at start
        return;
    }
    to = &source[start];
    from = &source[start + count];

    while(*from)//loop until '\0'
    {
        *to = *from;
        to++;
        from++;
    }
    //set '\0'
    *to = *from;
}

int stringLength(const char string[])
{
    int count =0;
    while(string[count] != '\0')
        count++;
    return count;
}
#包括
#包括
#包括
无效重新投资(字符源[],整数开始,整数计数);
int stringLength(const char string[]);
内部主(空)
{
int开始,计数;
int结果=0;
字符源[120];
字符输入[120];
printf(“您的字符串是什么?\n”);
if((fgets(source,sizeof(source,stdin))==NULL){
printf(“无法获取输入\n”);
返回1;
}
source[strcspn(source,“\n”)]='\0';//删除换行符
做{
printf(“要删除多少个字符?\n”);
if((fgets(输入,sizeof(输入),stdin))==NULL){
printf(“无法获取输入\n”);
返回1;
}
结果=sscanf(输入、%d、&count);
}while(result!=1);//在错误输入上循环
做{
printf(“我们从哪里开始?\n”);
if((fgets(输入,sizeof(输入),stdin))==NULL){
printf(“无法获取输入\n”);
返回1;
}
结果=sscanf(输入、%d、&start);
}while(result!=1);//在错误输入上循环
重新投资(来源、开始、计数);
printf(“这是结果:%s\n”,来源);
返回0;
}
无效重新投资(字符源[],整数开始,整数计数)
{
char*to=NULL,*from=NULL;
int length=stringLength(源);
如果(开始>长度){//非常短的源
返回;
}
如果(开始+计数>长度){//源仍然太短
source[start]='\0';//开始时截断
返回;
}
to=&source[start];
from=&source[开始+计数];
while(*from)//循环到“\0”
{
*to=*from;
to++;
来自++;
}
//设置“\0”
*to=*from;
}
int stringLength(常量字符字符串[])
{
整数计数=0;
while(字符串[计数]!='\0')
计数++;
返回计数;
}

不应该改为
for(j=(开始+计数)-1;j=start
吗?您不需要嵌套循环…只有一个循环和两个数组指示
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void removeString(char source[], int start, int count);
int stringLength(const char string[]);

int main(void)
{
    int start, count;
    int result = 0;
    char source[120];
    char input[120];

    printf("What's your string?\n");
    if ( ( fgets( source, sizeof ( source), stdin)) == NULL) {
        printf ( "could not get input\n");
        return 1;
    }
    source[strcspn ( source, "\n")] = '\0';//remove newline

    do {
        printf("How many characters do you want to remove?\n");
        if ( ( fgets( input, sizeof ( input), stdin)) == NULL) {
            printf ( "could not get input\n");
            return 1;
        }
        result = sscanf(input, "%d", &count);
    } while ( result != 1);//loop on bad input

    do {
        printf("Where are we starting from?\n");
        if ( ( fgets( input, sizeof ( input), stdin)) == NULL) {
            printf ( "could not get input\n");
            return 1;
        }
        result = sscanf(input, "%d", &start);
    } while ( result != 1);//loop on bad input

    removeString(source, start, count);

    printf("Here's the result: %s\n", source);
    return 0;
}

void removeString(char source[], int start, int count)
{
    char *to = NULL, *from =NULL;

    int length = stringLength(source);

    if ( start > length) {//very short source
        return;
    }

    if ( start + count > length) {//source still too short
        source[start] = '\0';//truncate at start
        return;
    }
    to = &source[start];
    from = &source[start + count];

    while(*from)//loop until '\0'
    {
        *to = *from;
        to++;
        from++;
    }
    //set '\0'
    *to = *from;
}

int stringLength(const char string[])
{
    int count =0;
    while(string[count] != '\0')
        count++;
    return count;
}