我正在书中练习,除了printf
和scanf
之外,我不允许使用任何库函数。
我写了一个接受字符串的程序。然后,您可以输入要从字符串中删除的字符数。然后选择执行哪个索引。
我的尝试是在我的函数结束时遍历我想要保留的字符,然后用我想要丢失的函数替换它们。
由于某种原因,它正好相反。
如果我输入字符串:"the wrong son"
然后选择删除6个字符并从数组的第4个索引开始,
我应该得到:"the son"
相反,我得到"the 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;
}
答案 0 :(得分:3)
你只需要一个for循环来实现这一点。假设我们可以成功地避免在字符串的末尾运行,你可以编写如下内容:
for(i = start; i < start + count && i < length; i++) {
source[i] = source[i+count];
}
然后你只需要在正确的位置设置一个空字符。但是,这不算数。也许在长度计数1(或考虑开始+计数),因为你正在删除&#34;计数&#34;字符。
答案 1 :(得分:1)
您需要修改循环 -
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()
这个循环基本上做的是,从start
(i
)位置初始化,并在索引{{1}处复制索引start+count
(j
)的值}。最后将i
附加到数组中。
同样关于'\0'
不正确,因为它会将其附加到错误的位置。
答案 2 :(得分:1)
考虑使用fgets读取输入,使用sscanf来解析整数。检查sscanf(或scanf)的返回以查看是否存在问题。在removeString
中,可以使用一对指针来遍历字符串。
#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;
}
答案 3 :(得分:0)
你能告诉我我哪里出错吗?
在索引中。
我会尝试让您了解出错的地方,而不是发布简单的解决方案。
for(i = (start+count); i <= length; i++)
在这里,对于输入错误的儿子&#39;,length
将等于13.因此,您正在索引source[13]
,不是一个越界访问,因为你已经将数组静态初始化为20个单元格,但它仍然超过输入字符串的长度1。
因此请将其更改为i < length
。
现在这个循环:
for(j = (start+count)-1; j <= start; j--)
它表示从9开始(对于示例输入)并减少j
直到它小于或等于4,没有意义,你打算写:
j >= start
现在抓一张纸,写下你的输入和指示,请:
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&#39;在应用我的修复后,对吧?
所以你要做的就是直到start
再加上你已经覆盖过的东西,并且不再次覆盖!
结果,改变这个:
j >= start
到
j >= start + i - (start + count);
你应该得到这个输出:
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
如果情况并非如此,请告诉我发布整个固定代码。
修改:
我附加了&#39; \ 0&#39;错了吗?
不,这是正确的(至少在此答案中提出的所有修正案之后)。我们来看看这段代码:
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,这是第二个&#39; n&#39;在字符串中,这正是我们想要放置空终止符的地方。