When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
160 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
to put it simple, how does strcat apply to arrays?
char chara1[10];
char char1 = 'a';
chara1[0] = 'a';
strcat(char1,chara1[0]);
best I can do
char chara1[10];
char char1;
char char2;
char1 = 'a';
char2 = 'a';
for(i=0;i<10;i++){
strcat(char1,char2);
chara1[i] = char2;
printf("%c",chara1[i]);
}
strcat only applies to arrays or char* since they are typically the same (you cannot append a character to a string)
actually i can be mistaken
try this:
#include <string.h>
#include <stdio.h>
int main(void) {
char str[7] = "Hello";
char appendant = '!';
strncat(str, &appendant, 1);
printf("%s", str);
}```
;compile
Hello!Hello!
;compile
<source>: In function 'main':
<source>:8:3: error: too many arguments to function 'strcat'
8 | strcat(str, &appendant, 1);
| ^~~~~~
In file included from <source>:1:
/usr/include/string.h:149:14: note: declared here
149 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
| ^~~~~~
Build failed
;compile
Hello!
?
;compile
<source>: In function 'main':
<source>:14:13: error: 'i' undeclared (first use in this function)
14 | for(i=0;i<10;i++){
| ^
<source>:14:13: note: each undeclared identifier is reported only once for each function it appears in
<source>:15:24: warning: passing argument 1 of 'strcat' makes pointer from integer without a cast [-Wint-conversion]
15 | strcat(char1,char2);
| ^~~~~
| |
| char
In file included from <source>:1:
/usr/include/string.h:149:39: note: expected 'char * restrict' but argument is of type 'char'
149 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
| ~~~~~~~~~~~~~~~~~^~~~~~
<source>:15:30: warning: passing argument 2 of 'strcat' makes pointer from integer without a cast [-Wint-conversion]
15 | strcat(char1,char2);
| ^~~~~
;compile
#include <string.h>
#include <stdio.h>
int main(void) {
char chara1[10];
char char1;
char char2;
char1 = 'a';
char2 = 'a';
for(int i=0;i<10;i++){
strcat(char1,char2);
chara1[i] = char2;
printf("%c",chara1[i]);
}
}```
<source>: In function 'main':
<source>:15:24: warning: passing argument 1 of 'strcat' makes pointer from integer without a cast [-Wint-conversion]
15 | strcat(char1,char2);
| ^~~~~
| |
| char
In file included from <source>:1:
/usr/include/string.h:149:39: note: expected 'char * restrict' but argument is of type 'char'
149 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
| ~~~~~~~~~~~~~~~~~^~~~~~
<source>:15:30: warning: passing argument 2 of 'strcat' makes pointer from integer without a cast [-Wint-conversion]
15 | strcat(char1,char2);
| ^~~~~
| |
| char
/usr/include/string.h:149:70: note: expected 'const char * restrict' but argument is of type 'char'
149 | extern char *strcat (char *__restrict __
you can't combine two non-string characters like that
what you can do is append a character to an array as shown here
if that's not what you want, what are you trying to do?
infact why use strcat here at all? why not just chara1[i] = 'a';
i want to:
add 'a' to 'a' in each loop, like
a
aa
aaa
then assighn to each array each loop
;compile
#include <stdio.h>
int main(void) {
char str[10];
for (int i = 0; i < 10; i++) {
str[i] = 'a';
printf("%s\n", str);
}
}```
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
like that?
ye
well is that exactly what you want?
ye
oh
then
isnt your problem solved? dont use strcat
just add a
😭
infact if you want to use strcat you can
can you explain that code to me, how does it add extra a?
;compile
#include <stdio.h>
#include <string.h>
int main(void) {
char str[10];
for (int i = 0; i < 10; i++) {
strncat(str, &(char){'a'}, 1);
printf("%s\n", str);
}
}
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
aaaaaaaaaaa
essentially think of an array as multiple chars in a line
you can read these chars left to right to get a string
if you for example, put 'a' in the line, past the second 'a'
then it will read aaa
here try doing your own concatenation
wow thats pretty construct =]
#include <stdio.h>
#include <string.h>
int main(void) { // code entrypoint - all execution starts here!
char str[10]; // create an array of 10 characters
for (int i = 0; i < 10; i++) { // repeat 10 times...
strncat(str, // copy _ to this array...
&(char){'a'}, // _ turns into 'a'...
1); // copy only one character to the string!
printf("%s\n", str); // then print the string out!
} // ends our repeat loop
} // and that's wraps!
another use is like this:
;compile
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[100] = "Hello ";
char str2[] = "World!";
strcat(str1, str2);
printf("%s", str1);
} ```
Hello World!
how does
printf("%s\n", str);
know what part of the array to output, there is no [ ]
i dont mean to be a pest, but the original idea was to assign array, example:
a[0] = a
a[1] = aa
a[2]= aaa
a[3]= aaaa
but assigned within a for loop
then you need an array of array of characters
simple
it's outputting the entire array
@dim dawn sry forgot to ping
No, it's not "outputting the entire array." Strings in C are characters placed one after another in memory. The only way a bare %s format specifier knows when to stop is when it hits a null terminator (just a zero in memory). This code:
#include <stdio.h>
int main(void) {
char str[10];
for (int i = 0; i < 10; i++) {
str[i] = 'a';
printf("%s\n", str);
}
}```Has undefined behavior, since we do not have a null terminator. The `%s` specifier has no way of knowing when to stop.
so
stg this server and its semantics
yes its outputting the entire thing until it hits the null terminator
💀
so in a case where all array charaqcters are full it is outputting the entire array 😭
although i didnt know that was ub
i thought for stack arrays that the null temrinator would be automatically placed at the end
It's not semantics. The str family of fuctions don't know when str will stop and the %s format specifier does not when when to stop.
This is fine:```c
#include <stdio.h>
int main(void) {
char str[10] = {0};
for (int i = 0; i < 9; i++) {
str[i] = 'a';
printf("%s\n", str);
}
}```Notice we initialize the array full of zeroes and stop just before the last element so we always have a null terminator
i know how it works
but i thought that was for char* and that again the null terminator was placed at the very end anyway
i also didnt know that this part initialized everything to 0
I believe C will always zero initialize global variables, but you usually don't want globals
You can use a plain 0 or '\0'
char ba[10][12];
strcpy(ba[0],"a");
for(int i=0;i<10;i++) {
strcpy(ba[i],ba[i-1]);
strcat(ba[i],"a");
}
=]
which outputs:
·⌂a
·⌂aa
·⌂aaa
·⌂aaaa
·⌂aaaaa
·⌂aaaaaa
·⌂aaaaaaa
·⌂aaaaaaaa
·⌂aaaaaaaaa
·⌂aaaaaaaaaa
and with i as 1:
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
there is no single a
int main() {
char ba[10][10];
strcpy(ba[0],"a");
for(int i=0;i<10;i++) {
strcpy(ba[i],ba[i-1]);
strcat(ba[i],"a");
printf("%s\n",ba[i]);
}
return 0;
}```
how do i compile this on here
;compile c
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
<source>: In function 'main':
<source>:9:1: warning: implicit declaration of function 'strcpy' [-Wimplicit-function-declaration]
9 | strcpy(ba[0],"a");
| ^~~~~~
<source>:2:1: note: include '<string.h>' or provide a declaration of 'strcpy'
1 | #include <stdio.h>
+++ |+#include <string.h>
2 |
<source>:9:1: warning: incompatible implicit declaration of built-in function 'strcpy' [-Wbuiltin-declaration-mismatch]
9 | strcpy(ba[0],"a");
| ^~~~~~
<source>:9:1: note: include '<string.h>' or provide a declaration of 'strcpy'
<source>:12:5: warning: implicit declaration of function 'strcat' [-Wimplicit-function-declaration]
12 | strcat(ba[i],"a");
| ^~~~~~
<source>:12:5: note: include '<string.h>' or provide a declaration of 'strcat'
<source>:12:5: warning: incompatible implicit declaration of built-in function 'strcat' [-Wbuiltin-declaration-mismatch]
<source>:12:5: note: include '<string.h>' or provide a declaration of 'strcat'
I think it does the lang automatically if you
`
`
`
c
how do I get that to show up in one msg ^
```c
oh, like that
#include <stdio.h>
#include <string.h>
int main() {
char ba[10][10];
//strcpy(ba[0],"z");
for(int i=0;i<10;i++) {
strcpy(ba[i],ba[i-1]);
strcat(ba[i],"a");
printf("%s\n",ba[i]);
}
return 0;
}
can someone explain this code for me:
strcpy(ba[i],ba[i-1]);
ba is an array of strings. So you're copying the string at index i - 1 into the string at index i
Because you don't print the string at index 0. That's the string that has the single 'a'
First and foremost, this is UB when i=0, you should start at i=1 and initialize your array like this: char ba[10][10] = {0};
It copies ba[i-1] into ba[i]
So lets say ba[i] starts as an empty string, so ba[0] is \0.
The loop then adds "a" to the end of that, so ba[1] becomes "a", and so on...
Unless the goal of this is to learn about 2d arrays, this is an odd way to do this...
Doing this, as Raccoon said, would be better.
minus 1?
-_-
i still dont understand
is the result equivalent adding 1 each time to the array?
ohhhhhhhhhhhhhh
You mean 1 'a'? yeah.
it copies the previous array to the next, then strcat adds another a?
Yes
Not sure I understand what you mean.
ba is looks like this if initialized to 0:
ba[0] = ""
ba[1] = ""
...
ba[9] = ""
Each ba[n] has space for 10 chars in it, i.e ba[n][0] to ba[n][9].
Lets say i = 1, doing ba[i - 1] would give us ba[0], which is empty i.e "", so the strcpy has no affect on the first iteration
strcat then adds "a" to the empty string, that makes ba[1] = "a".
why does there have to be ba[10][10];
can't it be done with just ba[10];
?
Because you want an array of strings.
A string in C is an array of characters.
i.e:
char str[13] = "Hello World!"
Is the same as:
char str[13];
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
...
str[11] = '!';
str[12] = '\0';
So an array of those would be char str[x][y].
Edit: Forgot to add terminator.
so, for example, does str[10][14] mean:
10 slots with up to a number of 14 length?
Yes
Thats good :)
Yea, at some point you'll get the hang of things and new concepts will be easy to understand.
check this out =]
#include <stdio.h>
#include <string.h>
int main() {
char chara[10][10];
int i;
for(i=0;i<10;i++){
strcpy(chara[i],chara[i-1]);
strcat(chara[i],"a");
}
for(i=9;i>-1;i--){
printf("%s\n",chara[i]);
}
return 0;
}
You have problems here again with the i-1. When i is 0, then i-1 is -1. You shouldn't be indexing by a negative
Before the for loop, fill the first value of chara with something like memcpy(chara[0],"a",2) and then start your for loop at 1 instead of 0. You won't be able to use strcpy for the very first string, since you don't have a null terminator yet
its copy the previous array to the current, thats the point
Yes, but there is no previous array to copy yet. That's why you need to initialize the first one
well ye, nul makes nothing happen, but just continues
Nothing is NULL or zero here
You don't initialize your arrays with anything so it's just garbage memory that would be something called "undefined behavior" to access. Undefined behavior means your code can do literally anything it wants to at that point and C would be okay with it because your program is invalid
Then you try to index the array with -1. A negative index won't wrap around to the end, it tries to access the memory before your array in memory. This is also undefined behavior. You are accessing out of the bounds of the array
That's the scary part about undefined behavior. It might work on your machine with that specific compiler, but as soon as anything changes, anything can happen
You could get a Segmentation Fault for reading out of bounds depending on where your program loads up into memory, for example.
Raccoon is completely correct here, accessing an array like that can very easily go wrong.
You can easily end up accessing either other stack variables or even data that's not on your current stack.
;compile c -O0
#include <stdio.h>
int main()
{
int a[5] = {0};
int b = 10;
printf("b is at %p and a[-1] is at %p\n", &b, &a[-1]);
for (int i = 0; i < 5; i++)
printf("a[i] = %d, a[i - 1] = %d\n", a[i], a[i - 1]);
}
b is at 0x7ffc40cd264c and a[-1] is at 0x7ffc40cd264c
a[i] = 0, a[i - 1] = 10
a[i] = 0, a[i - 1] = 0
a[i] = 0, a[i - 1] = 0
a[i] = 0, a[i - 1] = 0
a[i] = 0, a[i - 1] = 0
ye it could go wrong, but in the right circumstance it should be fine
Look again, I added the addresses.
See how we end up accessing b.
In your example it happened to work because chara[-1] was 0, but that's not always the case.
You shouldn't depend on "In the right circumstances". Switching to a different compiler, or doing something as simple as adding an extra printf could break your code.
And that's why UB is bad, it could break.
Note that in my example I explicitly initialized a to zeros, you also don't do that.
Uninitialized data could be anything leftover from previous functions that used the stack.
I'll give an example for that too.
;compile c -O0
#include <stdio.h>
int main()
{
int nums[100];
for (int i = 0; i < 100; i++)
printf("%d\n", nums[i]);
}
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
64
0
8
0
64
0
0
0
-1
-1
0
0
0
0
25
1
1
2
-1280659708
32765
419331063
29551
0
0
2
0
6
-2147483648
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
4194368
0
419268668
29551
1776
0
-1280661495
3276
Simply initializing like this: int nums[100] = {0}; makes all the garbage data go away.
Raccoon and Vexed are correct, but no justification about potential output is needed. Your program invokes undefined behavior. As per the standard your program is invalid. That is as far as it goes.
problem with this code
itoa(int1[i],chara1[i]);
i think there might need a ,10 after chara1[1]
or something
the output of this code is scrambled, any help?
int i;
int int1[10];
char chara1[10][10];
char chara2[10][10];
//int1[0] = 0;
for(i=0;i<10;i++){
itoa(int1[i],chara1[i],30);
strcpy(chara2[i],chara1[i-1]);
strcat(chara2[i],chara1[i]);
printf("%s\n", chara2[i]);
}
its supposed to output:
0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
I'm not sure what else to tell you at this point with respect to undefined behavior. This code suffers from the same problems as your previous snippets have.
ive got something
int int1[10];
char chara1[10][10];
char chara2[10][10];
//int1[0] = 0;
for(i=0;i<10;i++){
int1[i] = i;
itoa(int1[i],chara1[i],26);
strcat(chara1[i],chara1[i-1]);
printf("%s\n",chara1[i]);
}```
which outputs
0
10
210
3210
43210
543210
6543210
76543210
876543210
9876543210
which is backwards
looks like it needs 1 adjustment
!solved
Thank you and let us know if you have any more questions!
This thread is now set to auto-hide after an hour of inactivity