【问题标题】:C function for converting text to morse code用于将文本转换为摩尔斯电码的 C 函数
【发布时间】:2020-04-22 14:07:07
【问题描述】:

我正在尝试编写一个程序,其中需要系统给定文本的莫尔斯电码。关于将文本转换为莫尔斯电码,我将它们全部写在 main 中(与程序文件本身分开)。现在,我的目标是将它写成一个函数,以便在程序的其他函数中使用它。每当我尝试时,它都会出现分段错误。谁能帮我从头开始构造函数本身?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdint.h>
#include<ctype.h>
#include <time.h>

char * fileName1 = NULL;
char * fileName2 = NULL;

int main(int argc, char * argv[]) {
  int n;
  for (n = 0; n < argc; n++) {
    // printf("Argument %s\n",argv[n]); // prints options  delete this in the end,just for debugging
    if (strcmp(argv[n], "-text") == 0) {
      //text to morsecode
      int c, v = 0;
      char * str = (char * ) malloc(v);
      str = (char * ) realloc(str, (c + strlen(argv[n + 1])));
      strcat(str, argv[n + 1]);
      strcat(str, " ");

      char *alphamorse[]={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
      char *nummorse[]={"-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};

      int i;
      char str1[1000];
      i = 0;
      while (str[i] != '\0') {
        if (str[i] != ' ' && (!isdigit(str[i]))) {
          printf("%s ", alphamorse[toupper(str[i]) - 65]);
        }
        if (str[i] == ' ') {
          printf(" ");
        }
        if (isdigit(str[i]) && str[i] != ' ') {
          printf("%s ", nummorse[str[i] - 48]);
        }
        i++;
      }
      printf("\n");
      // end of text to morsecode
    }
    if (strcmp(argv[n], "-o") == 0) {
      //output = concat(output, argv[n + 1]);
      n++;
      continue;
    }
    if (strcmp(argv[n], "--") == 0) {
      if (n + 1 <= argc) {
        fileName1 = argv[++n];
        printf("    fileName1=%s\n", fileName1);
      }
      if (n + 1 <= argc) {
        fileName2 = argv[++n];
        printf("    fileName2=%s\n", fileName2);
      }
    }
  }
  return 0;
}

【问题讨论】:

  • 我假设幻数 65 和 48 旨在表示 A0。在代码中使用这样的数字而不是 'A''0' 是不好的做法,这不仅是为了便于阅读,而且因为这些值会根据字符集而改变。

标签: c function segmentation-fault main morse-code


【解决方案1】:

您确实不需要或不想复制参数。这样做似乎最简单:

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

char *alphamorse[] = {
        ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", /* A - J */
        "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", /* K - T */
        "..-", "...-", ".--", "-..-", "-.--", "--.." /* W - Z */
};
char *nummorse[]={
        "-----", ".----", "..---", "...--", "....-",
        ".....", "-....", "--...", "---..", "----."
};

void
text_to_morse(char c, FILE *out)
{
        if( islower(c) ) {
                fputs(alphamorse[c - 'a'], out);
                fputc(' ', out);
        } else if( isdigit(c) ) {
                fputs(nummorse[c - '0'], out);
                fputc(' ', out);
        } else if( isspace(c) ) {
                fputc(c, out);
        } else {
                fputc(' ', out);
        }
}

int
main(void)
{
        int c;
        while( ( c = tolower(getchar())) != EOF ) {
                text_to_morse(c, stdout);
        }
        return 0;
}

甚至不用费心处理输出文件的代码。外壳的存在是有原因的,无需重新实现轮子。

【讨论】:

  • 嗨!如果函数必须由用户从终端获取文本,而不是从文件中获取文本怎么办?如果我需要使用从函数获取的数据本身作为莫尔斯电码怎么办?
  • 从标准输入读取文本。如果用户想从终端输入它,他们将使用来自终端的标准输入运行程序。如果用户希望数据来自文件,他们将使用来自文件的标准输入运行程序。如果你需要使用这些数据,你可以传递一个从 fmemopen 创建的 FILE *。
【解决方案2】:

我不知道这是否是导致问题的错误,但这是一个错误:

int c, v = 0;
char *str = (char *)malloc(v);
    str = (char *)realloc(str, (c + strlen(argv[n+1])));

首先,c 未初始化。它可以是任何值,包括负值。因此,您的程序中有未定义的行为。

另外,不需要 malloc 后跟 realloc 调用。只需分配一次即可完成。

我认为这是你打算做的

size_t len = strlen(argv[n+1]);
str = (char*)malloc(len + 1 + 1); // +1 for space char to be appended, +1 again for null char
strcpy(str, argv[n+1]); // copy string
strcat(str, " ");       // append a space

但还有一个更简单的解决方案。您甚至不需要将argv[n+1] 复制到str。只需将str 声明为指针并直接引用argv[n+1]

const char* str = argv[n+1];

现在strargv[n+1] 引用相同的字符串。 str 对整个程序有效。程序的其余部分保持不变。

这看起来很可疑:

  i = 0;
  while (str[i] != '\0') {
    if (str[i] != ' ' && (!isdigit(str[i]))) {
      printf("%s ", alphamorse[toupper(str[i]) - 65]);
    }
    if (str[i] == ' ') {
      printf(" ");
    }
    if (isdigit(str[i]) && str[i] != ' ') {
      printf("%s ", nummorse[str[i] - 48]);
    }
    i++;
  }

您重复调用 isdigit 并进行评估以确保 str[i] 不是空格。如果您已经知道它是一个数字,那么检查它是否是一个空格是没有意义的。要么是数字,要么是字母,要么是无法转换的东西。您的代码将错误地将标点符号视为要在 alphamorse 中查找的值。以下将跳过标点符号并将这些字符视为空格。

  i = 0;
  while (str[i] != '\0') {

    if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z')) {
      printf("%s ", alphamorse[toupper(str[i]) - 'A']);
    }
    else if (isdigit(str[i])) {
      printf("%s ", nummorse[str[i] - '0']);
    }
    else {
        printf(" ");
    }
    i++;
  }

之后的一切,我都不知道是为了什么。一般建议是首先解析来自argv[] 的参数。然后在迭代命令行参数的循环之外进行文本转换。然后保存到文件代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2015-03-18
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2018-06-08
    • 2013-02-12
    相关资源
    最近更新 更多