简体   繁体   English

从字符串中打印偶数和奇数字符的程序

[英]A program that prints even and odd characters from a string

This is for Homework 这是为家庭作业

I have to write a program that asks the user to enter a string, then my program would separate the even and odd values from the entered string. 我必须编写一个程序,要求用户输入一个字符串,然后我的程序将输入的字符串中的偶数和奇数值分开。 Here is my program. 这是我的计划。

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

int main(void) {
    char *str[41];
    char odd[21];
    char even[21];
    int i = 0; 
    int j = 0;
    int k = 0;

    printf("Enter a string (40 characters maximum): ");
    scanf("%s", &str);

    while (&str[i] < 41) {
        if (i % 2 == 0) {
            odd[j++] = *str[i];
        } else {
            even[k++] = *str[i];
        }
        i++;
    }

    printf("The even string is:%s\n ", even);
    printf("The odd string is:%s\n ", odd);

    return 0;
}

When I try and compile my program I get two warnings: 当我尝试编译我的程序时,我得到两个警告:

  1. For my scanf I get "format '%s' expects arguments of type char but argument has 'char * (*)[41]" . 对于我的scanf我得到"format '%s' expects arguments of type char but argument has 'char * (*)[41]" I'm not sure what this means but I assume it's because of the array initialization. 我不确定这意味着什么,但我认为这是因为数组初始化。

  2. On the while loop it gives me the warning that says comparison between pointer and integer. while循环中,它给出了警告,指出指针和整数之间的比较。 I'm not sure what that means either and I thought it was legal in C to make that comparison. 我不确定这意味着什么,我认为在C中进行比较是合法的。

When I compile the program, I get random characters for both the even and odd string. 当我编译程序时,我得到偶数和奇数字符串的随机字符。

Any help would be appreciated! 任何帮助,将不胜感激!

this declaration is wrong: 这个宣言是错的:

char *str[41];

you're declaring 41 uninitialized strings. 你宣布41个未初始化的字符串。 You want: 你要:

char str[41];

then, scanf("%40s" , str); 然后, scanf("%40s" , str); , no & and limit the input size (safety) ,没有&和限制输入大小(安全)

then the loop (where your while (str[i]<41) is wrong, it probably ends at once since letters start at 65 (ascii code for "A"). You wanted to test i against 41 but test str[i] against \\0 instead, else you get all the garbage after nul-termination char in one of odd or even strings if the string is not exactly 40 bytes long) 那么循环(你的while (str[i]<41)是错误的,它可能会立即结束,因为字母从65开始(ascii代码为“A”)。你想测试i对41但是测试str[i]反对\\0而不是,如果字符串不是40字节长的话,你会在oddeven字符串之一中获得nul-termination char之后的所有垃圾)

while (str[i]) {
    if (i % 2 == 0) {
        odd[j++] = str[i];
    } else {
        even[k++] = str[i];
    }
    i++;
}

if you want to use a pointer (assignement requirement), just define str as before: 如果你想使用指针 (assignement requirements),只需像以前一样定义str

char str[41];

scan the input value on it as indicated above, then point on it: 如上所示扫描输入值,然后指向它:

char *p = str;

And now that you defined a pointer on a buffer, if you're required to use deference instead of index access you can do: 现在您在缓冲区上定义了一个指针,如果您需要使用deference而不是索引访问,则可以执行以下操作:

while (*p) { // test end of string termination
    if (i % 2 == 0) {  // if ((p-str) % 2 == 0) { would allow to get rid of i
        odd[j++] = *p;
    } else {
        even[k++] = *p;
    }
    p++;
    i++;
}

(we have to increase i for the even/odd test, or we would have to test p-str evenness) (我们必须为偶数/奇数测试增加i ,否则我们必须测试p-str均匀度)

aaaand last classical mistake (thanks to last-minute comments), even & odd aren't null terminated so the risk of getting garbage at the end when printing them, you need: aaaand最后一个经典错误(感谢最后一分钟的评论), evenodd都不会被终止,因此在打印它们时最终会得到垃圾的风险,你需要:

even[k] = odd[j] = '\0';

(as another answer states, check the concept of even & odd, the expected result may be the other way round) (作为另一个答案陈述,检查偶数和奇数的概念,预期结果可能是相反的方式)

There are multiple problems in your code: 您的代码中存在多个问题:

  • You define an array of pointers char *str[41] , not an array of char . 你定义了一个指针数组char *str[41] ,而不是char数组。
  • You should pass the array to scanf instead of its address: When passed to a function, an array decays into a pointer to its first element. 您应该将数组传递给scanf而不是其地址:当传递给函数时,数组会衰减为指向其第一个元素的指针。
  • You should limit the number of characters read by scanf . 您应该限制scanf读取的字符数。
  • You should iterate until the end of the string, not on all elements of the array, especially with (&str[i] < 41) that compares the address of the i th element with the value 41 , which is meaningless. 你应该迭代直到字符串的结尾,而不是数组的所有元素,特别是使用(&str[i] < 41)将第i个元素的地址与值41 ,这是没有意义的。 The end of the string is the null terminator which can be tested with (str[i] != '\\0') . 字符串的结尾是空终止符,可以使用(str[i] != '\\0')
  • You should read the characters from str with str[i] . 你应该用str[i]读取str的字符。
  • You should null terminate the even and odd arrays. 你应该null null evenodd数组。

Here is a modified version: 这是一个修改版本:

#include <stdio.h>

int main(void) {
    char str[41];
    char odd[21];
    char even[21];
    int i = 0; 
    int j = 0;
    int k = 0;

    printf("Enter a string (40 characters maximum): ");
    if (scanf("%40s", str) != 1)
        return 1;

    while (str[i] != '\0') {
        if (i % 2 == 0) {
            odd[j++] = str[i];
        } else {
            even[k++] = str[i];
        }
        i++;
    }
    odd[j] = even[k] = '\0';

    printf("The even string is: %s\n", even);
    printf("The odd string is: %s\n", odd);

    return 0;
}

Note that your interpretation of even and odd characters assumes 1-based offsets, ie: the first character is an odd character. 请注意,您对偶数和奇数字符的解释假定基于1的偏移,即:第一个字符是奇数字符。 This is not consistent with the C approach where an even characters would be interpreted as having en even offset from the beginning of the string, starting at 0. 这与C方法不一致,其中偶数字符将被解释为甚至从字符串的开头偏移,从0开始。

here is your solution :) 这是你的解决方案:)

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

int main(void) 
{

    char str[41]; 
    char odd[21];
    char even[21];
    int i = 0; 
    int j = 0;
    int k = 0;

    printf("Enter a string (40 characters maximum): ");
    scanf("%s" , str); 

    while (i < strlen(str)) 
    {
        if (i % 2 == 0) {
                odd[j++] = str[i];
        } else {
                even[k++] = str[i];
        }
        i++;
    }
    odd[j] = '\0'; 
    even[k] = '\0';

    printf("The even string is:%s\n " , even);

    printf("The odd string is:%s\n " , odd);

    return 0;
}

solved the mistake in the declaration, the scanning string value, condition of the while loop and assignment of element of array. 解决了声明中的错误,扫描字符串值,while循环的条件以及数组元素的赋值。 :) :)

Many answers all ready point out the original code`s problems. 许多答案都准备好指出原始代码的问题。

Below are some ideas to reduce memory usage as the 2 arrays odd[], even[] are not needed . 下面是一些减少内存使用的想法,因为不需要 2个数组odd[], even[]

As the "even" characters are seen, print them out. 当看到“偶数”字符时,将它们打印出来。
As the "odd" characters are seen, move them to the first part of the array. 当看到“奇数”字符时,将它们移动到数组的第一部分。

Alternative print: If code used "%.*s" , the array does not need a null character termination. 替代打印:如果代码使用"%.*s" ,则数组不需要空字符终止。

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

int main(void) {
  char str[41];

  printf("Enter a string (40 characters maximum): ");
  fflush(stdout);
  if (scanf("%40s", str) == 1) {
    int i;
    printf("The even string is:");
    for (i = 0; str[i]; i++) {
      if (i % 2 == 0) {
        str[i / 2] = str[i];  // copy character to an earlier part of `str[]`
      } else {
        putchar(str[i]);
      }
    }
    printf("\n");
    printf("The odd string is:%.*s\n ", (i + 1) / 2, str);
  }
  return 0;
}

or simply 或者干脆

printf("The even string is:");
for (int i = 0; str[i]; i++) {
  if (i % 2 != 0) {
    putchar(str[i]);
  }
}
printf("\n");
printf("The odd string is:");
for (int i = 0; str[i]; i++) {
  if (i % 2 == 0) {
    putchar(str[i]);
  }
}
printf("\n");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM