I'm trying to write a program where the morse code of the given text by the system is required. About the converting text to morse code, I wrote them all in main (separately from the program file itself). And now, my aim is to write it as a function in order to use it in the other functions of the program. Whenever I try, it gives a segmentation fault. Can anyone help me to construct the function itself from scratch?
#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;
}
I don't know if this is the bug that's causing an issue, but it is a bug:
int c, v = 0;
char *str = (char *)malloc(v);
str = (char *)realloc(str, (c + strlen(argv[n+1])));
First, c
is uninitialized. It could be any value, including a negative value. Hence, undefined behavior in your program.
Also, that malloc followed by a a realloc call isn't needed. Just allocate once and be done with it.
I think this is what you intended to do
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
But there's an even simpler solution. You don't even need to copy argv[n+1]
into str
. Just declare str
as a pointer and reference argv[n+1]
directly.
const char* str = argv[n+1];
Now str
and argv[n+1]
reference the same string. And str
is valid for the entirety of the program. The rest of your program remains the same.
This looks suspicious:
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++;
}
You are redundantly calling isdigit and evaluating to make sure str[i]
is not a space. No point in checking if its a space if you already know it's a digit. Either it's a digit, a letter, or something that can't be converted. Your code will errneously treat puncutation marks as values to lookup in alphamorse
. The following will skip over punctuation marks and just treat those characters as spaces.
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++;
}
Everything after that, I don't know what it's for. General advice is that you parse the arguments from argv[]
first. Then do the text conversion outside of the loop that iterates over the command line arguments. Then do your save to file code.