Array unwanted characters in C - c

Ok,I am beginner in C.I was thought that for a array to hold to characters in need to declare it as:
char a[10];
So I will have 10 elements from (0 to 9)
but it is not working.It is giving me unwanted characters.Can you tell me the problem is.My code:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
printf("%s",rand_string());
}
int rand_string(void)
{
srand(time(NULL));
char a[7];
int e;
int d;
a[0]='l';
a[1]='o';
a[2]='n';
a[3]='g';
a[4]=' ';
d=(rand()%6) + 97;
a[5]=d;
e=(rand()%10) + 48;
a[6]=e;
printf("\n%s\n",a);
return a;
}
I get results like:
long f99
|/
What I expect:
long f9
Ok so in total I have 4 questions:
*How to fix the problem of unwanted characters and why is it giving unwated characters?
*Is my way of generating random numbers with limit ok?
*how to write the first 4 letters "long" in one line rather that for each line in an array?
*How to combine 2 strings?

You need to NULL terminate your string. Extend the array by one and add a[7] = 0; in there and you'll be set.
Editorial note: Your program has another big problem in that you are returning a pointer to a local variable. You may want to change rand_string to fill in a buffer provided by main instead. Here's a quick example with both of these modifications:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void rand_string(char a[8])
{
srand(time(NULL));
int e;
int d;
a[0]='l';
a[1]='o';
a[2]='n';
a[3]='g';
a[4]=' ';
d=(rand()%6) + 97;
a[5]=d;
e=(rand()%10) + 48;
a[6]=e;
a[7]=0;
printf("\n%s\n",a);
}
int main(void)
{
char buffer[8];
rand_string(buffer);
printf("%s", buffer);
return 0;
}

The first question is already answered by Carl Norum.
Is my way of generating random numbers with limit ok?
Yes, but defining a function would be nice, wouldn't it? Calling like a[0] = randomBetween(97, 102); is much more readable though.
EDIT: As in a comment above stated: you even could write
a[0] = randomBetween('a', 'f'); Just a little bit more readable ;-)
how to write the first 4 letters "long" in one line rather that for each line in an array?
There is no way, instead you could copy the elements in a loop or using a function like memcpy, strcpy. Taking your question wordly:
a[0] = 'l'; a[1] = 'o'; a[2] = 'n'; a[3] = 'g';
But this is not what you want, I guess :-) See also the strcpy-example below.
How to combine 2 strings?
Again, either using a loop or the functions mentioned above:
char *first = "Hello ";
char *second = "World";
char combined[12];
int currentIndex = 0, i = 0;
// copy characters from "first" as long we did not find a \0
while(first[i] != 0)
combined[currentIndex++] = first[i++];
i = 0;
// copy characters from "second" as long we did not find a \0
while(second[i] != 0)
combined[currentIndex++] = second[i++];
// finally don't forget to null-terminate!
combined[currentIndex] = 0;
Using e.g. strcpy is much easier ;-)
char *first = "Hello ";
char *second = "World";
char combined[12];
strcpy(combined, first);
strcpy(&combined[6], second);
What are we doing here? The first strcpy-call copies simply "first" to "combined". But the second calls seems to be interesting. There we copy "second" to the 7th position (start counting from 0, therefor 6). At this position was the \0-character after the first function call. But we don't want the string to end here, so we override it with the first character of the second string. One nice thing is that strcpy automatically copies the terminating \0 at the end. Quite simple, isn't it?

Related

C recursive function to reverse a string without pointers, string.h, or external variables [duplicate]

There is this problem on LeetCode that I can not get to work in C/C++
The idea is to reverse an array in its place (using no other additional array) using recursion.
The link is : https://leetcode.com/explore/learn/card/recursion-i/250/principle-of-recursion/1440/
The solution is done in Java or Python.
I tried implementing the solution in C but I always get the original array, my code is as follows:
void reverseString(char* s, int sSize){
if(!s)
return;
reverseString(s+1,sSize-1);
s[sSize] = *s;
}
There is something I am not accounting for. Please let me know how would you solve it, and if possible why this is not working. Thanks.
I'll take a stab at this.
The general idea for a recursive solution is for each call to get a pointer to the start of a string, and how many characters to look at, and this walks its way to the middle of the string.
void reverseString(char *start, int n)
{
if (n <= 1) return;
char tmp = start[0];
start[0] = start[--n]; // the nth character is start[n-1]
start[n] = tmp;
reverseString(++start, --n);
}
On each recursive call, the starting string pointer is incremented by one, and the length decreased by two.
FIRST CALL: v v
hello, world
SECOND CALL: ^ ^
The common danger area is making sure it does the right thing with even and odd-length strings.
This method is a bit simpler with just two parameters, and - as some might say - a bit more elegant :-) even if the ++ and -- could be considered tricky (one increment and two decrements).
EDIT: This version is also tail recursive, which can lead to certain optimizations by internally turning it into a loop.
Solution (thank you to the folks in the comments):
void reverse(char * str, int len)
{
char tmp;
if (len <= 1)
return;
tmp = str[0];
len--;
str[0] = str[len];
str[len] = tmp;
str++;
reverse(str, len-1);
}
Call this function with your initial string and 0 as arguments:
char str[] = "Ding dong";
reverse(str, 0, strlen(a));
void reverse_string(char *x, int start, int end)
{
char ch;
if (start >= end)
return;
ch = *(x+start);
*(x+start) = *(x+end);
*(x+end) = ch;
//Function calling itself: Recursion
reverse_string(x, ++start, --end);
}
In this function we are passing the string, the starting index and the ending index.... The recursion will continue till start>=end i.e. till the center of the string appears..... And everytime it will swap the 2 indexes i.e. from the start and from the end...

Flip Array Recursively

There is this problem on LeetCode that I can not get to work in C/C++
The idea is to reverse an array in its place (using no other additional array) using recursion.
The link is : https://leetcode.com/explore/learn/card/recursion-i/250/principle-of-recursion/1440/
The solution is done in Java or Python.
I tried implementing the solution in C but I always get the original array, my code is as follows:
void reverseString(char* s, int sSize){
if(!s)
return;
reverseString(s+1,sSize-1);
s[sSize] = *s;
}
There is something I am not accounting for. Please let me know how would you solve it, and if possible why this is not working. Thanks.
I'll take a stab at this.
The general idea for a recursive solution is for each call to get a pointer to the start of a string, and how many characters to look at, and this walks its way to the middle of the string.
void reverseString(char *start, int n)
{
if (n <= 1) return;
char tmp = start[0];
start[0] = start[--n]; // the nth character is start[n-1]
start[n] = tmp;
reverseString(++start, --n);
}
On each recursive call, the starting string pointer is incremented by one, and the length decreased by two.
FIRST CALL: v v
hello, world
SECOND CALL: ^ ^
The common danger area is making sure it does the right thing with even and odd-length strings.
This method is a bit simpler with just two parameters, and - as some might say - a bit more elegant :-) even if the ++ and -- could be considered tricky (one increment and two decrements).
EDIT: This version is also tail recursive, which can lead to certain optimizations by internally turning it into a loop.
Solution (thank you to the folks in the comments):
void reverse(char * str, int len)
{
char tmp;
if (len <= 1)
return;
tmp = str[0];
len--;
str[0] = str[len];
str[len] = tmp;
str++;
reverse(str, len-1);
}
Call this function with your initial string and 0 as arguments:
char str[] = "Ding dong";
reverse(str, 0, strlen(a));
void reverse_string(char *x, int start, int end)
{
char ch;
if (start >= end)
return;
ch = *(x+start);
*(x+start) = *(x+end);
*(x+end) = ch;
//Function calling itself: Recursion
reverse_string(x, ++start, --end);
}
In this function we are passing the string, the starting index and the ending index.... The recursion will continue till start>=end i.e. till the center of the string appears..... And everytime it will swap the 2 indexes i.e. from the start and from the end...

Copying part of an array into another variable

So I'm trying to copy part of an array into another array in the simplest way possible. I was trying to avoid using a loop. This was my thought process...
char date[]="20140805";
char year =date[0..3];
The ".." is what is causing the error. I want to be able to break up the date variable into parts, and was hoping to be able to do so compactly in one line like this. Some help would be appreciated.
You should not use a loop.
char year[5];
char date[] = "20140805";
memcpy(year, date, 4);
year[4] = 0;
that's how you should do it, or may be you want
char date[] = "20140805";
char year[] = {date[0], date[1], date[2], date[3], 0};
Here is an example to do that :
In fact you can copy any part of a string using this method :)
just change the from and sz variable and you are done :)
#include <stdio.h>
#include <string.h>
int main ()
{
char date[]= "20140805";
int sz=4; // number of characters to copy
char year[sz+1];
int from = 0; // here from is where you start to copy
strncpy ( year, date + from, sz );
year[sz]=0;
puts (year);
return 0;
}
OP wanted a one-liner: here in one declaration plus one line.
char year[5] = {0};
strncpy(year,date,4);
This answer addresses the weak point of strncpy() which does not append a final 0 if count <= strlen(source);. It's not the best solution but it answers OP's question while avoiding the trap.
Byte dumps of the char array before and after the strncpy()
0 0 0 0 0
50 48 49 52 0

Find size of input char* and copy portion to output char* C

I have a char array LL,4014.84954 that I send into a function like this example:
#include <stdio.h>
#include <math.h>
void myFunction(char* in_string, char* out_string) {
printf("Start_String=%s\n", in_string);
int in_size = (int)(sizeof(in_string));
printf("%d\n", in_size);
int i = 0;
for(i = 0; i <= in_size-ceil(in_size/2); i++) {
out_string[i] = in_string[i];
}
}
int main(int arg) {
char in_string[] = "LL,4014.84954";
char out_string[] = "";
printf("In_String=%s\n", in_string);
myFunction(in_string, out_string);
printf("Out_String=%s\n", out_string);
}
My question has two parts.
How do I get the length of this char array? int in_size = (int)(sizeof(in_string)); in this example gives me 8 which is the size of the pointer (long int). I know I could make a for loop that marches through until it see the null termination, but is there a nicer way? I previously was using char[] and sizeof works great, but now I am converting to char*.
How can I write a portion of these chars to out_string. My example currently writes all chars to out_string.
Here is the raw output:
In_String=LL,4014.84954
Start_String=LL,4014.84954
8
Out_String=LL,40014.84954
(1)
Answer to question 2:
char out_string[] = "";
out_string[] is of only one size. you assigning out_string[i] = ... for i > 0 is wrong and cause an undefined error. Instead of this you should declare out_string[] like this:
out_string[] = malloc(strlen(in_string) + 1);
// ^ extra for \0 char
(2)
additionally #WhozCraig commenting correct, you actually need strlen() to find length of string. sizeof you are using wrong.
So replace:
int in_size = (int)(sizeof(in_string));
by
int in_size = strlen(in_string);
(3)
Also, what is in_size-ceil. As I can understands from your raw output you don't need such kind of function and calculations. Just replace your for loop:
for(i = 0; i <= in_size-ceil(in_size/2); i++)
by
for(i = 0; i < in_size; i++)
(4)
At the end don;t forget to terminate you string out_string, after for loop add this line
out_string[i] = '\0'
Regarding your first question, use strlen().
Regarding the second question, first of all you need to make sure that out_string is wide enough to accommodate the result. Currently, it isn't, and the behaviour of your code is undefined. Once you fix that, to copy a portion of the string you'd need to change the initial and final conditions of the for loop, not forgetting about the NUL terminator.

Some questions concerning a C integer to string function

Whilst reading through K&R, I came across the integer to string function. I gave it a quick read, and decided to implement it myself, but instead of printing, it updates a character array.
Here is what I have
void inttostr(int number, char str[]) {
static int i;
if (number / 10) {
inttostr(number / 10, str);
}
str[i++] = number % 10 + '0';
}
It seemed to work for the few integers I gave it, but I have some questions.
I haven't explicitly included the nul byte \0 at the end, so why does the string work fine when printed with printf("%s\n", str);?
I don't think I'm very good at thinking recursively. When I try and step through the program in my mind, I lose track of what is still awaiting execution. Is there a better way of seeing what is happening internally, to help me learn?
Any other suggestions on the code?
I'm using Xcode.
This is not homework. I'm just learning.
Thanks!
You're correct that you're never writing NUL, which is a bug.
In general, you don't have to think through the entire solution. You just have to make sure every step is correct. So in this case, you say:
1 . inttostr(number / 10, str);
will take care of all but the last digit.
2 . Then I will take care of the last one.
You can trace what's happening, though. For e.g. 54321 it looks like:
inttostr(54321, str); // str = ...;
inttostr(5432, str); // str = ...;
inttostr(543, str); // str = ...;
inttostr(54, str); // str = ...;
inttostr(5, str); // str = ...;
str[0] = '5'; // str = "5...";
str[1] = '4'; // str = "54...";
str[2] = '3'; // str = "543...";
str[3] = '2'; // str = "5432...";
str[4] = '1'; // str = "54321...";
Note that when you don't return from any of the functions until you write the first character, then you return in the opposite order from the calls.
The ... signifies that you haven't NUL-terminated. Another issue is that you're using a static variable, so your code isn't reentrant; this means it breaks in certain scenarios, including multi-threading.
To address the reentrancy and NUL issue, you can do something like the code below. This creates a helper function, and passes the current index to write.
void inttostr_helper(int number, char str[], int *i)
{
if (number / 10) {
inttostr_helper(number / 10, str, i);
}
str[(*i)++] = number % 10 + '0';
str[*i] = '\0';
}
void inttostr(int number, char str[])
{
int i = 0;
inttostr_helper(number, str, &i);
}
EDIT: Fixed non-static solution.
I am impressed of the creativity to use recursive, despite that it is not necessary. I think the code should remove statically-allocated i variable because this variable will persist through calls. So the second time you use this function from your code, e.g. from main(), it will not be initiated and will be the same value from previous call. I would suggest using return value as follow:
int inttostr(int number, char *str) {
int idx = 0;
if (number / 10) {
idx = inttostr(number / 10, str);
}
str[idx++] = number % 10 + '0';
return idx;
}
1, Your compiler (especially in debug mode) may have filled str with 0. Unix does this if you allocate memory with new() - But don't rely on this, either set the first byte to \0 or memset everything to 0
2, paper + pencil. Draw a table with each variable across the top and time down the side.
3, Write the simplest, longest version first, then get clever.
I haven't explicitly included the nul byte \0 at the end, so why
does the string work fine when printed
with printf("%s\n", str);?
how is the original char array declared when you call your function the first time? if it is a static char array then it will be filled with 0's and that would explain why it works, otherwise its just "luck"
I don't think I'm very good at thinking recursively. When I try and
step through the program in my mind, I
lose track of what is still awaiting
execution. Is there a better way of
seeing what is happening internally,
to help me learn?
honestly, I am not sure if anybody is good in thinking recursively :-)
Did you try drawing the execution step by step?

Resources