Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
My program need to print all the ABC but I see I have problems with the code. How I can fix it? (no pointer for this time).
What is the runtime error in the code and how to fix it?
Here is the code:
// Elvis’s hip and happening ABC-printing code
#include <stdio.h>
#include <string.h>
#define NUM_ABC_LET 26
void makeABC(char abc[NUM_ABC_LET]);
int main() {
char abcString[NUM_ABC_LET] = "";
makeABC(abcString);
puts(abcString);
return (0);
}
void makeABC(char abc[NUM_ABC_LET]) {
char letter;
for (letter = 'a'; letter <= 'z'; letter++) {
strcat(abc, letter);
}
}
The problem is that the strcat function expects both arguments to be (zero-terminated) strings. You only pass one string, and then one single character as arguments (which should give you compiler warnings).
You need to convert this single characters into a string (or an array) of a single character.
And don't forget that strings in C are zero-terminated.
What happens you use the single character as argument to the strcat function is that the compiler converts it to an int which is then in turn converted to a pointer. The problem with this is that the address 'a' (for example) is not a valid address to a string. That will lead to undefined behavior and a crash.
Your program logic is correct, the problem is the calling of the strcat() function. The strcat() function is implemented as:
char *strcat(char *dest, const char *src)
{
char *ret = dest;
while (*dest)
dest++;
while (*dest++ = *src++);
return ret;
}
The second argument must be a string instead which you pass a character.
This is the reason for your run time error.
Can you try something like following? I haven't tested the following but it should work on most part.
// Elvis’s hip and happening ABC-printing code
#include <stdio.h>
#include <string.h>
#define NUM_ABC_LET 26
void makeABC(char abc[NUM_ABC_LET]);
int main()
{
char abcString[NUM_ABC_LET + 1];
makeABC(abcString);
puts(abcString);
return 0;
}
void makeABC(char abc[NUM_ABC_LET + 1])
{
char letter;
int i=0;
for(letter = 'a'; letter <= 'z'; letter++)
{
abc[i] = letter;
i++;
}
abc[i]='\0';
}
Your program has several issues:
You cannot call strcat with a char, you must pass char * arguments, pointing to null terminated C strings.
The array into which you compose the alphabet is too short: you need to define it with a size one larger than the number of characters for the final '\0' terminator.
Here is a corrected version:
#include <stdio.h>
#include <string.h>
#define NUM_ABC_LET ('z' - 'a' + 1) // 26 ASCII letters
void makeABC(char *abc); // makeABC receives a pointer to an array of char
// this declaration is equivalent to
// void makeABC(char abc[NUM_ABC_LET+1]);
// but less error prone
int main(void) {
char abcString[NUM_ABC_LET + 1] = "";
makeABC(abcString);
puts(abcString);
return 0;
}
void makeABC(char *abc) {
char letter;
char buf[2]; // a buffer for a 1 letter C string
for (letter = 'a'; letter <= 'z'; letter++) {
buf[0] = letter; // make a 1 letter string
buf[1] = '\0'; // set the null terminator
strcat(abc, buf);
}
}
Prototype of strcat is
char *strcat(char *destination, const char *source);
means our source as well as destinations should and must be string so this is the issue that why if you compile in turbo c it will through error of
"type mismatch".
and if you wanna write program for printing ABC up to Z than simply write
void main()
{
int i;
for(i = 65; i<=90; i++)
{
printf("%c", i);
}
}
I hope you will like it......
As a slight variation, I would suggest passing the length of the character array to the function, so that the function does not overflow the array.
As the character array is passed to the function as a pointer, the function does not know it's size.
In your case you know the size, but for the future it might be better to explicitly pass the size.
Also I just copied the characters rather than use strcat, and added the null termination at the end.
#include <stdio.h>
#define NUM_ABC_LET 26
/* function takes pointer to array and size of array */
void makeABC(char *abc, int len);
int main()
{
/* array needs to include space for null termination */
char abcString[NUM_ABC_LET + 1];
/* call function with pointer + size */
makeABC(abcString, NUM_ABC_LET);
printf("%s\n", abcString);
return (0);
}
void makeABC(char *abc, int len)
{
int n;
for(n = 0; n < len; n++ ) {
/* add letters to the array */
abc[n] = n + 'a';
}
/* put a null termination on the end */
abc[n] = '\0';
}
Related
Trying to do Exercise 1-19 of K&R 2nd ed., e.g. writing a function to reverse a string. I thought I managed, but the print output looks strange :-) If I use STRINGSIZE 5 the output is
Original String: hello
Reversed String: ollehhello. If I use STRINGSIZE 6 to keep in mind the '\0' string end character and modify the while-loop to while ((outputString[STRINGSIZE - (i + 2)] = inputString[i]) != '\0'), then I get Original String: hello
Reversed String: olleh?hello, I guess the ? is some random character coming from a '\0' added to the reversed string in the while-loop at position 5; but hello is again added. Could anyone explain how come hello gets added to the end of olleh and how can I get rid of it so that I only get the proper reversed string ?
Here is the code:
#include <stdio.h>
#define STRINGSIZE 5
void reverseString (char inputString[], char outputString[]);
int main(void) {
char stringToReverse[] = "hello";
char reversedString[STRINGSIZE];
reverseString(stringToReverse, reversedString);
printf("Original String: %s\nReversed String: %s\n", stringToReverse, reversedString);
}
void reverseString (char inputString[], char outputString[]) {
int i;
i = 0;
while ((outputString[STRINGSIZE - (i + 1)] = inputString[i]) != '\0')
++i;
}
First, the character array reversedString[] does not have enough space to store the null terminator of the string "hello". One option is to use a variable length array here:
char reversedString[strlen(stringToReverse) + 1];
VLAs were introduced in C99, and made optional in C11. As I remember it, K&R does not include coverage of variable length arrays, since even the 2nd edition was published before this.
Another option that would be compatible with C89 is to use the sizeof operator:
char stringToReverse[] = "hello";
char reversedString[sizeof stringToReverse];
Here, the result from the sizeof operator is known at compile time, and can be used in the declaration of a fixed size array. This size includes space for the null terminator, in contrast to the result from strlen("hello"). Note that this would not work with char *stringToReverse = "hello";, since then the sizeof operator would give the size of a pointer. This also would not work if stringToReverse had been passed into a function first, since then the array name would have decayed to a pointer to the first element of stringToReverse.
In the reverseString() function, the length of inputString needs to be determined (since STRINGSIZE is no longer being used); this can be done with strlen(), or in a loop. Then, critically, the function must be certain to add a null terminator (\0) to outputString[] before returning. Also note that a return statement has been added to the end of main() to make this truly C89 compatible:
#include <stdio.h>
void reverseString (char inputString[], char outputString[]);
int main(void) {
char stringToReverse[] = "hello";
char reversedString[sizeof stringToReverse];
reverseString(stringToReverse, reversedString);
printf("Original String: %s\nReversed String: %s\n",
stringToReverse, reversedString);
return 0;
}
void reverseString(char inputString[], char outputString[])
{
int length = 0;
int i = 0;
/* Get inputString length; or use strlen() */
while (inputString[length] != '\0') {
++length;
}
/* Copy to outputString[] in reverse */
while (i < length) {
outputString[i] = inputString[(length - i) - 1];
++i;
}
/* Add null terminator */
outputString[i] = '\0';
}
First I'll suggest that you change this line:
char reversedString[STRINGSIZE];
to
char reversedString[strlen(stringToReverse) + 1]; // + 1 to make room for the string termination
Then I would do something like:
void reverseString (char inputString[], char outputString[]) {
int i;
int len = strlen(inputString);
for(i=0; i<len; ++i)
{
outputString[len-i-1] = inputString[i];
}
outputString[len] = '\0'; // Terminate the string
}
i'm learning c and i got a analyse question...
i got this code:
#include <stdio.h>
#include <string.h>
#define NUM_ABC_LET 26
void makeABC(char abc[NUM_ABC_LET]);
int main()
{
char abcString[NUM_ABC_LET] = "";
makeABC(abcString);
puts(abcString);
return (0);
}
void makeABC(char abc[NUM_ABC_LET])
{
char letter;
for(letter = 'a'; letter <= 'z'; letter++)
{
strcat(abc, letter);
}
}
can any one tell me why will it crash all the time? and what problems it has?
You need to reserve space for 26 alphabets + 1 for the NUL-terminator('\0').
So change
char abcString[NUM_ABC_LET] = "";
to
char abcString[NUM_ABC_LET + 1] = "";
and NUL-terminate it just after the loop in makeABC by using
abc[NUM_ABC_LET] = '\0';
Also, as #BLUEPIXY has mentioned in the comments, strcat requires both its arguments to be strings(char*), but you pass a char* and a char and this causes things to mess up as it invokes Undefined Behavior. So, replace
strcat(abc, letter);
with something like
abc[letter - 'a'] = letter;
I need to write a probram in C, which adds a string to a string etc. (for example '5' strings - It needs to read "vbvbvbvbvb" 5 times.) But it doesn't work? Help please!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[80];
int len;
int counter = 0;
char* repeat(char* s, int n) {
if (n > 0) {
if (s[len] == n) {
counter++;
}
len--;
repeat(s, (n++));
}
return s;
}
int main(void) {
printf("%s", repeat("vb", 5));
fflush(stdout);
return EXIT_SUCCESS;
}
You're trying to write into the end of "vb" which is a string in the constant pool. Don't do that. Allocate a string that is strlen(s) * n + 1 long and write into that.
Your base case is probably wrong. The base case should probably be when n == 0 which is when the empty string (nothing appended except terminating NUL as below) is appropriate.
Your recursive step (n++) should probably be (n - 1) to count down to that base case. As written, the post-increment does a useless assign and recurses with the same value of n.
I don't know what counter and len are supposed to do, but they looks redundant to me. len is uninitialized, so s[len] has undefined behavior.
After writing the n copies, you need to add a terminating NUL ('\0') at the end so that printf and similar functions can identify the end.
You are using s both as a global and a local variable, the function is working on the local.
Try not to use global variables where not necessary. Also, recursion is not necessary for this.
#include <stdio.h>
void concatenate_string(char *dest, const char *src, int n) {
char *s;
while(n--) {
s = (char*)src;
while(*(s))
*(dest++)=*(s++);
}
*(dest++) = 0;
}
int main(void) {
char out[80];
concatenate_string(out, "ab", 5);
printf("%s", out);
return 0;
}
I am trying to write a function, uppercase, that converts all lowercase characters in a string into their uppercase equivalents.
However, I am getting a Bus 10 error in my code. I know that string literals cannot be modified in C; so, I am not sure if this is the right approach.
My code is below:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
int uppercase(char source[])
{
int i;
for(i=0; i<=strlen(source); ++i)
if (source[i]>= 'a' && source[i]<= 'z')
source[i]= source[i]-'a' +'A';
else
source[i]=source[i];
}
int main(){
uppercase("cold");
return 0;
}
Ideally this function should return COLD.I suppose the error lies in my whole if statement.
The reason you get a crash is that your code modifies a string literal. Characters inside string literals are placed in protected memory area, and therefore may not be changed: it us undefined behavior.
Replace this
uppercase("cold");
with this:
char cold[] = "cold";
uppercase(cold);
Now the characters of the string are placed in a modifiable area of memory, allowing you to make changes as needed.
Your absolutly working with pointers without even to know it.
In your function definition
int uppercase(char source[])
char source[] is considered by the compiler as a pointer to char (char *source)
So when passing a string literal to uppercase() your just passing it's adress. Then in your function your trying to modify it which leads to undefined behaviour.
Also you can't return a whole array so you just return a pointer to it.
char *uppercase(char source[])
{
int i;
size_t len = strlen(source);
char *tmp;
tmp = malloc(len+1);
if (tmp!=NULL){
memcpy(tmp, source, len+1);
for(i=0; i<len; ++i){
if (tmp[i]>= 'a' && tmp[i]<= 'z'){
tmp[i]= tmp[i]-'a' +'A';
}
}
}
return tmp;
}
Then:
int main(){
char *str = uppercase("cold");
printf("%s", str);
free(str);
return 0;
}
You complete code: http://ideone.com/BJHDIF
I have the following code:
#include <stdio.h>
void insertion_sort(char[], int);
void swap(char*, char*);
int main() {
char s[] = "hello world";
puts(s);
insertion_sort(s, sizeof(s)/sizeof(char));
puts("done\n");
puts(s);
return 0;
}
void swap(char* a, char* b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
void insertion_sort(char s[], int n)
{
int i,j;
/* counters */
for (i=1; i<n; i++) {
j=i;
while ((j>0) && (s[j] < s[j-1])) {
swap(&s[j],&s[j-1]);
j = j-1;
}
printf("%s\n", s);
}
}
The problem is, after the insertion_sort() function call, s becomes empty - puts(s) prints nothing.
Please advise.
Change:
insertion_sort(s, sizeof(s)/sizeof(char));
to:
insertion_sort(s, strlen(s));
otherwise you will be including the '\0' terminator of s[] in your sort.
Note that you will need an additional header for strlen so change:
#include <stdio.h>
to:
#include <stdio.h> // printf etc
#include <string.h> // strlen etc
The problem is that the length that you pass to insertion_sort includes terminating \0 character, which happens to have value 0, so in sort it is placed as the first element of your array. This is why your last puts() prints nothing - because the first character is now "the end of a string".
I suggest you to calculate the size of a string using strlen() which will return the length of a string excluding terminating character. Or if you want to do it your way, take terminating character into consideration and substract it from the total length.