What is wrong with my C code? C code error [closed] - c

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 4 years ago.
Improve this question
I am very new in C programming. can someone please tell me what is wrong with this code I am trying to run this code.
int main(void)
{ char source[10];
char *dest; size_t i;
strcpy(source, "0123456789");
dest = malloc(strlen(source));
for (i = 1; i <= 11; i++) {
dest[i] = source [i];
}
dest[i] = '\0';
printf("dest = %s", dest); return 0; 13. }
Thanks a lot in advance

Firstly, allocate enough memory for source to hold 0123456789. And this dest[i] = '\0'; causes undefined behavior as here you are trying to access(dest[10]) something which you didn't allocate. So allocate enough memory for dest to store '\0' at the end. For e.g
dest = malloc(strlen(source) + 1);/* +1 is for \0 char as strlen(source) doesn't include \0 */
Secondly, don't think that source[0] is integer zero 0 its a character zero i.e '0'(ascii - 48). So you no need to start rotating form i=1, rotate from i=0 and upto '\0'.
This
for (i = 1; i <= 11; i++) { /* array index starts from 0 */
dest[i] = source [i];
}
Should be
for (i = 0;source[i]; i++) { /* when \0 encounters, loop terminates */
dest[i] = source [i];
}

Related

remove duplicates in a string with a buffer [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I’m trying to remove duplicates in a string using a map. Running it through GDB I'm not able to figure out where the code is failing, though the logic to me seems right.
Could anyone please point out the mistake?
int main() {
char *str="I had my morning tea";
int len = strlen(str);
int dupArr[256] = {0};
//Build the map
int i=0;
for(i;i<256;i++)
dupArr[str[i]]++;
//If the count is 1 then print that value.
i=0;
for(i;i<256;i++) {
if(dupArr[str[i]] == 1) {
printf("%c\n",str[i]);
}
}
}
output
I h y o r i g t % c 4 # } ` 8 � F J
I get up to 't' ,which is correct but then i see magic chars.
Your string has length of len but you are traversing till 256 which is out of bound.
Use len when inserting into the hash.
int i=0;
for(i;i<LEN;i++)
dupArr[str[i]]++;
Also if your are checking the duplicates then it should be bigger than 1 since your are ++ the first encountered char
if(dupArr[str[i]] > 1)
In addition to Mark Ezberg's good answer, note that dupArr[str[i]]++; poses a problem when str[i] < 0.
Better to treat the characters as unsigned char:
int dupArr[UCHAR_MAX + 1] = {0};
....
dupArr[(unsigned char) str[i]]++;
Rolling this and other ideas together:
int main(void) {
char *str="I had my morning tea";
size_t dupArr[UCHAR_MAX + 1] = {0};
unsigned char *s = (unsigned char *) str;
while (*s) {
dupArr[*s]++;
s++;
}
for(unsigned i = 0; i <= UCHAR_MAX; i++) {
// A duplicate is when dupArr[i] is _more_ than 1.
if(dupArr[i] > 1) {
printf("%c\n",str[i]);
}
}
}

Segmentation Fault:11 in C [closed]

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
I am writing a program in C that replaces a number in a char* called "template" with a string, but I continually get a Segmentation Fault: 11 error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *rep_str(const char *s, const char *old, const char *new1){
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);
for (i = 0; s[i] != '\0'; i++){
if (strstr(&s[i], old) == &s[i]){
count++;
i += oldlen - 1;
}
}
ret = (char*)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s){
if (strstr(s, old) == s){ //compare the substring with the newstring
strcpy(&ret[i], new1);
i += newlen; //adding newlength to the new string
s += oldlen;//adding the same old length the old string
} else {
ret[i++] = *s++;
}
}
ret[i] = '\0';
return ret;
}
char* madlib_by_numbers(char* temp, int word_count, char* words[]){
char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int tempSize = strlen(temp);
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
return temp;
}
int main() {
char* temp1 = "The 1 0 likes to 2 in the moonlight.";
char* words[] = {"git", "brilliant", "swim"};
char* result = "The brilliant git likes to swim in the moonlight.";
int stringLength = strlen(result);
char* test = madlib_by_numbers(temp1, 3, words);
assert(strncmp(test, result, stringLength) == 0);
free(test);
return 0;
}
and when I run the debugger, it simply says: Segmentation Fault: 11
What i just want to understand is where the segmentation fault error is coming from, I have the suspicion one of my loops is running too many times.
There are a few issue with your code. However, the direct answer to your question is in this loop:
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]);
}
You are calling rep_str for every digit while you mean call rep_str only if the digit in temp matches the corresponding digit in numbers. So add this conditional if(strcmp(temp,numbers[j]) == 0) right before the line temp=.... Then it'll solve your current problem.
The segfault is caused because there are only three elements in the words array. Your old loop indexes from 0 to 9 and fails when j=3, out of bound.
Also, delete the free() at the end of your program. test was never allocated and will cause a core dump.
ret = (char*)malloc(i + count * (newlen - oldlen));
There are a few problems with this line of code.
For a start, don't cast malloc (or any void * that you're assigning to a variable of different pointer type, or vice versa).
If you intended to allocate space to store a string, where's the string-terminating '\0' going to go? You need to realise that for an empty old string, this will be malloc(0) and zero bytes is not enough to store an empty string.
There's also a problem if you expect that old may be a substring of new (for example, you're replacing "0" with "hell0"). You'll need to tweak your algorithm to handle this problem. I'll leave that as a challenge for you to attempt :)
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
users previous answer highlighted this code correctly, but not for the right reason... and so the solution he/she presented is wrong.
isdigit(temp[i]) may also cause segfaults for some inputs. I recommend using isdigit((unsigned char) temp[i]) instead, in this case.
It's not valid to access words[j] where word_count is 3 and j is greater or equal to 3; you're accessing that array out of bounds.
You also need to be careful to free any memory you *alloc (while simultaneously not freeing memory that you don't *alloc). Forgetting to do the former won't cause crashes, but your program won't run happily; it'll use heaps of memory.
Consider something like this, instead:
temp = strdup(temp);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
if (isdigit((unsigned char) temp[i])){
for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
char *new = rep_str(temp, numbers[j], words[j]);
free(temp);
temp = new;
}
}
}

strlen and free memory [closed]

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
I allocated memory to a pointer to the maximum size of characters it could have.
Then I had to write code that will change its values depending on the value that was read from the file and I needed to know what is the length of the value in the pointer, so I used strlen() function.
I got what I needed.
The problem occured when I tried to free the memory of that pointer. The program crashed, I'm assuming im doing something "ilegal" and would like to know why and how to fix it.
here is part of the code:
char *StudID = (char*)malloc(sizeof(char)*15);
char *StudIDcpy = (char*)malloc(sizeof(char) * 15);
fread(stud[i].ID, sizeof(char), 4, in);
stud[i].ID[4] = '\0';
IDtemp = atoi(stud[i].ID);//convert ID string to integer and store value in IDtemp
StudIDcpy = itoba(IDtemp);//convert integer to binary number as a string
strcpy(StudID, StudIDcpy);
IDtemp = strlen(StudIDcpy);
free(StudIDcpy); // <---- I BELIEVE THIS IS WHERE IT CRASHES
Here is my itoba() function:
char *itoba(int a){
int i = 0, j;
char temp[15];
while(a){
if (a % 2)temp[i] = '1';
else temp[i] = '0';
i++;
a = a / 2;
}
temp[i] = '\0';
for (j = 0; j < i / 2; j++)swapc(&temp[j], &temp[i - j-1]);
return temp;
}
By the way I know I don't have to write sizeof(char) because it is equal to 1, but I write it anyways so I remember what value should be put there.
In your itoba() function, temp, a local array, which decays to a pointer to local variables, is returned.
After a function returns, its local variables are "free"ed immediately, allowing these memory space to be reused by someone else. Consequently, values held by them will soon be overridden by other values on the stack.
You can rewrite itoba() like this:
char *itoba(int a)
{
int i = 0, j;
char *temp = malloc(15); // <--- This line is different
while(a){
if (a % 2)
temp[i] = '1';
else
temp[i] = '0';
i++;
a = a / 2;
}
temp[i] = '\0';
for (j = 0; j < i / 2; j++)
swapc(&temp[j], &temp[i - j -1]);
return temp;
}
BTW: You should remove char *StudIDcpy = (char*)malloc(sizeof(char) * 15);, because the pointer value returned by malloc() is later discarded by itoba(IDtemp);. As a result, the memory allocated to StudIDcpy by this malloc() will never be freed, causing memory leak.

Problems with creating a function to reverse a string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
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.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I need to create a fuction that returns a string. So far I have come up with this code:
#include <stdio.h>
#include <string.h>
#define SIZE 256
void str_reverse(char[SIZE], char[SIZE]);
int main(void)
{
char input[SIZE];
char output[SIZE];
printf("Please enter a string\n");
fgets(input, SIZE, stdin);
str_reverse(input, output);
printf("%s \n", output);
return 0;
}
void str_reverse(char in[SIZE], char out[SIZE])
{
int i = strlen(in);
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
}
However, whenever I try to run the code, I do not get an output. Does anyone have any idea what could be wrong
The problem is this line
int i = strlen(in);
Change it to
int i = strlen(in)-1;
strlen() returns the size of the string, hence when you start copying from in[], in[j] would be \0. which is getting stored in out[0].
Another change you need to do is put a \0 in the out[], just after the for loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
Your "reversing" includes the null character too. So the reversed string's first character is '\0'. So the string is empty.
Change:
for(int j = i ; j>= 0; j--)
to
for(int j = i - 1; j>= 0; j--)
You should also check if the string length is zero before the for loop. Otherwise, i-1 will become SIZE_MAX and you'll have problems with that!
A simple condition such as the following in str_reverse() would handle that case:
size_t i = strlen(in);
int k = 0;
if (i<=1) return; //empty string or contains only 1 char char.
i starts out at strlen(in), so the first character you copy over tooutis the null byte at the end of the string. Every other character then appears after the null terminator, soout` is an empty string.
Start with i at strlen(in) - 1, then add the null terminator and the end of the loop:
int i = strlen(in) - 1; // start at the last non-null character
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0'; // add the null terminator
When k is 0 and j is i, you do the following:
out[0] = '\0';
Hence, out looks like an empty string when the function returns.
Use:
for(int j = i-1; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
In the function variable i is set the following way
int i = strlen(in);
So within the loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
then j is equal to i then in[j] is equal to the terminating zero '\0' of string in. Thus array out starts from zero that is it will contain an empty string.
It is better to declare the function itself the following way
char * str_reverse( char *out, const char *in );
and to return from the function the pointer out. In this case you could write for example
puts( str_reverse( output, input ) );
Take into acount that function fgets usually also stores the new line character in the string. You should remove it. you can do it the following way
input[strcspn( input, "\n" )] = '\0';
Also instead of the type int in this statement
int i = strlen(in);
it is better to use type size_t.
size_t i = strlen(in);
It is the type of the return value of the function strlen. But in this case you should also to write the loop correctly.:)

Is this reverse string function in C poorly written ? / How to make this code better? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Here is a part of code which describes a function to reverse characters of a string
(Based on exercise 1-19 of Brian W. Kernighnan Programming in C)...
( I have googled various text reverse function, but all of them us pointers or using strrev(), but I don't have an idea what a pointer is.... nor do I want to use strrev(), hence I made a reverse string function as the author wanted it to be........ )
The function:
void reverse(char s[])
{
int i , n ;
char j ;
i = 0 ;
while(s[i] != '0') //And not EOF
{
++n;
}
for(i = 0; i < n; ++i)
{
j = s[i] ;
s[i] = s[n - 1] ;
s[n - 1] = j ;
}
}
However I think overwritting arrays is bad , and the whole function seems awry.
P.S : It would be great if you did check and help me with the whole code here, since it would be offtopic if I did post it here, The code's main return 0; however it still doesn't work....
[EDIT]
Ok I am seriously sorry for troubling you for a typo... I can't delete this question since it has answers with upvotes however I'm sorry....
The correct function would be :
void reverse(char s[])
{
int i, l;
char temp;
for (l = 0; s[l] != '\0'; ++l);
l--;
for (i = 0; i < l; ++i) {
temp = s[i];
s[i] = s[l-1];
s[l-1] = temp;
--l;
}
}
Full Code is here :
Code
Code Working is here :
UPDATE:
I created a correct and working solution for the word 'hello':
#include <stdio.h>
int main(void)
{
char s[] = "hello";
char temp;
// do the swapping here..
temp = s[0];
s[0] = s[4] ;
s[4] = temp ;
temp = s[1] ;
s[1] = s[3] ;
s[3] = temp ;
temp = s[2] ;
s[2] = s[2] ;
s[2] = temp ;
printf("%c, %s ", temp, s);
}
I don't know where you got this piece of code, but it's actually quite broken:
n is never initialized. This is undefined behavior.
The while loop won't terminate at all because it compares a char with a value that is not in the range of a char.
The while loop can't do anything sensible since its body can't change the loop condition.
The for loop exchanges all characters with one single array element, which effectively rotates the string right by one char. But the program will never reach this point anyway.
The loop
while(s[i] != EOF)
{
++n;
}
seems wrong.
String end is checked via 0, not via EOF.
You never change i, so that you always check s[0].

Resources