Copying part of an array into another variable - c

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

Related

Program that finds every other character in the first half of a char array in C

This is the first part of the program and I have a few questions on how parts of it work exactly. Keep in mind this is the first C program I have written. scanf("%d",&numberOfTimes); Why do I need the & and what does it do?
char input[][200]; Is this basically an array of strings or is it something completely different?
#include <stdio.h>
#include <string.h>
char outputs[100];
char input[][200];
int numberOfTimes;
void io(void){
scanf("%d", &numberOfTimes);
for(int i = 0; i < numberOfTimes; i++){
scanf("%s",input[i]);
}
}
This next part of the code is my attempt at actually solving the problem however I suspect that I screwed up the use of a function but I don't know which one or I used something improperly in order to get this result. (I provided example i/o of me code at the bottom).
void stringManipulation(char string[200]){
int strLength = strlen(string);
int number = strLength/2;
for(int i = 0; i <= number; i=i+2){
strcat(outputs,&string[i]);
}
}
int main(void) {
io();
for(int i = 0; i < numberOfTimes; i++) {
stringManipulation(input[i]);
printf("%s\n",outputs);
memset(&outputs[0], 0, sizeof(outputs));
}
return 0;
}
Did I use memset properly? Again I don't understand the use of the &.
Example input:
4
your
progress
is
noticeable
Expected output:
y
po
i
ntc
Output I am getting:
yourur
progressogressress
is
noticeableticeableceable
Thank you for your help.
The & before a variable means that you are referring to the address of the variable, and not the variable value itself. If you don't know about what the address of a variable is : http://www.cquestions.com/2010/02/address-of-variable-in-c.html
char input[][200] is an array of char array (a char array is vulgarized as a string but it ISN'T the TYPE).
Your problem is about your strcat use, you're adding characters that are between string[i] (included) and string[strLength], not only the string[i] character.
Your problem is in strcat:
Your code passes the address and hence you are getting the entire string from that character onward.
strcat(outputs,&string[i]);
Now, change the above code as below:
strcat(output,string[i]);
You'll get the desired output. The problem with your initial code was that you were passing the address and not individual character.
Also, change the for loop in such a way that "<"number and not "<="number.
Let me know if you have any more doubts.

How to rewrite an char array in c?

I've searched around for a quiet some time but surprisingly I couldn't find an answer to it:
I want to rewrite a char array starting from [0], but all what's happening is: it's always appending. Here's my code:
The algorithm is: I have a very long string which I like to break into several lines (wherever there is a blank space at the end of a line). Each line shall be saved in an array Index (lineContent);
void print_text(char* content, int menu_width, int which_selected, int menu_height, int scroll_pos)
{
int posCounter = 0;
int charCounter = menu_width-10;
int printOutCounter;
char* lineContent[400]; // 400 lines max
short spaceFound;
while (strlen(content) > menu_width) // If string is longer than 1 line
{
//Interesting Part ---------- START
char changeString [strlen(content)];
char printString [menu_width-10];
spaceFound = 0;
charCounter = menu_width-10;
lineContent[posCounter] = malloc(MAXITEMSTR);
while (spaceFound == 0)
{
if (content[charCounter] == ' ')
{
// I guess the error goes between here ...
strncpy(changeString,content,strlen(content));
strncpy(printString,content,menu_width-10);
// ...and here
memmove(&changeString[0], &changeString[charCounter], strlen(content));
content=changeString;
lineContent[posCounter]=printString;
strcat(lineContent[posCounter],"\0");
posCounter++;
spaceFound = 1;
//Interesting Part ---------- END
}
charCounter--;
if (charCounter <= 0)
spaceFound = 1;
}
}
}
As I said, in the end, when checking the content of lineContent, every entry is the same (the one from the last line).
I think this is because, strcpy just appends to the end, therefor I have to clear the array, to erase the former line. So it will start from [0] and not from the last printed letter.
Has anybody an idea how to do this? Is there a function that overwrites a char array instead of appending it?
Kind Regards
Strcat appends to the end, strcpy overwrites the value stored in the string.

Array unwanted characters in 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?

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.

How can I add two strings?

of size 5, that I want to add, according to some conditions that I will impose. Both strings are in the format 00:00. The first string (s1) represents a certain time of departure of a plane, the second one, is how delayed that departure will be...
This is supposed to be done on a 24h clock.
Let's say, for example
s1=10:45
s1=01:50
so first I have to add the 5 and the 0, see if there's a carry out and if the result is under 9, then add the 4 and the 5, see if the result is under 6. If it isn't I subtract 6 to the addition and add the carry out (1) to the 0 and the 1, then I'll add 1 to 0.
5+0=5
4+5=9 9-6=3 carry out:1
0+1+1=2
0+1=1
12:35
What I would like to obtain is s1=12:35
I don't really get how pointers work... I've tried to understand them, but it was in vain...
Can you help me?
I have some ideas that I will post here:
#include <stdio.h>
#include <string.h>
char*add_hours(char s1[], char s2[])
int i;
for(i=4; i>3; i--){
if(s1[i]+s2[i]>9){
strcpy(s1[i], ((s1[i]+s2[i])-10);
strcpy(s1[i-1], (s1[i-1]+1));
}
...
}
the code goes on for a little while, but it repeats itself a few times. So I didn't think I needed to copy it all here. The problem is, he keeps telling me showing this warning:
"warning: passing argument 1 of 'strcpy' makes pointer from integer without a cast
/usr/include/string.h:128: note: expected 'const char * _restrict_' but argument if of type 'int'
And the same thing for the second argument, for every strcpy there is... I understand the error (I think) but I don't know how to correct it...
I may be wrong, but I think you don't want to add like that.
What happens if you have a depature at 00:30 and an arrival at 04:00, but daylight savings happens inbetween?
Populate a time_t structure. Convert that to a time_t. Add your delay, in seconds. Convert that back to a time_t. Print that out using strftme(). Let the time code in the C library deal with all these issues.
First, you should remove the for loop. It just makes 2 iterations and it is confusing.
Then, the first line of your function should be
char * sum = new char[5];
since you probably want to return a new string. It will also make things clearer.
Try to decompose things in order to simplify your problem. Start writing:
int minutes(char * s);
int hours(char * s);
That respectively return the number of minutes and hours expressed in a string.
strcpy expects strings (array of char/char pointer) as its parameters. What you are giving it are single characters. If you want to modify single characters that way, there is no need to use strcpy.
#include <stdio.h>
#include <string.h>
char*add_hours(char s1[], char s2[])
int i;
for(i=4; i>3; i--){
if(s1[i]+s2[i]>9){
s1[i] = (s1[i]+s2[i])-10;
s1[i-1] = s1[i-1]+1;
}
...
}
There are other logical problems with the code, but this should get you started.
#include <stdlib.h>
#include <string.h>
const int MINS_IN_HR = 60;
int StrToMins(char* str)
{
int res = 0;
char temp[3];
temp[2] = '\0';
memcpy(temp, str, 2);
res += atoi(temp)*MINS_IN_HR;
memcpy(temp, str+3, 2);
res += atoi(temp);
return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
char* s1="10:45", *s2="01:50";
int totalMins = StrToMins(s1) + StrToMins(s2);
printf("%d:%d", totalMins / MINS_IN_HR, totalMins % MINS_IN_HR);
return 0;
}

Resources