Hello guys, i have this code:
#include <stdio.h>
int main()
{
int numberPosition=8;
char senha[1000]="01000hello";
printf("%i\n", numberPosition);
senha[numberPosition]="";
printf("\n%s\n", senha);
return 0;
}
When I executes my code my return is: 01000heo.
However if I delete the line "printf("%d\n", numberPosition);" my return is: 01000helo
Why printf deletes an element from my array?
senha[numberPosition]=""; is problematic as the left side is expecting a char but the right side is a char * which is then implicitly cast to an integer. This is often an error and gcc will generate a warning. Here is the explicit cast:
senha[numberPosition]=(unsigned long) "";
This will convert the address where the string "" is stored to an integer. It happens to evaluate to 8 which is backspace \b:
./a.out | od -a
0000000 8 nl nl 0 1 0 0 0 h e l bs o nl
0000016
what you want, what you really, really want is:
senha[numberPosition]='\0';
which will print:
8
01000hel
You clarified you wanted the output "01000helo" and either of these produce that output for me:
#include <stdio.h>
int main() {
int numberPosition=8;
char senha[1000]="01000hello";
senha[numberPosition] = 'o';
senha[numberPosition+1] = '\0';
printf("%s\n", senha);
}
or:
#include <stdio.h>
#include <string.h>
int main() {
int numberPosition=8;
char senha[1000]="01000hello";
strcpy(senha + numberPosition, "o");
printf("%s\n", senha);
}
It would be a good idea to add boundary checks.
Your comment below talks about removing characters which is a different problem that you initially described. You want to check out memmove() (which permit overlap of dst, src, unlike strcpy(), memcpy()).
Related
I use vscode as my code editor, and in the header file <strings.h> there is a function called bzero and when hovering on the function vscode says that bzero Set N bytes of S to 0. But I don't think it works like that. I created an array of 11 chars which called s and placed inside it Hello World.
Then I used bzero to set the first 4 bytes of s to 0, but from the output it seems like it cleaned the whole buffer.
#include <strings.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
char s[11] = "Hello World";
bzero(s, 4);
puts(s);
return 0;
}
$ cc main.c -o main && ./main
# empty
$
bzero does exactly what it says. The issue you’re facing is due to a misunderstanding of what a string is in C.
Briefly, a C string is a zero-terminated buffer of chars. That is, C treats an array of chars as a string by considering all chars until it finds the first one whose value is 0.
puts (and printf etc.) uses this definition of “string”.
As a consequence, setting even just the first char in the array to 0 results in an empty string, regardless of what comes after.
(Note also that bzero is a legacy function and its use is discouraged; use memset instead.)
Zero is a string-terminating character. Therefore if you set the first byte of your string to zero, puts will believe that the string is empty.
puts() expects a pointer to a string. Strings in C is sequences of characters *terminated by a null-character ('\0'). Null-character is represented by a value zero.
Therefore, puts() stops at the first zero and prints an empty string.
Print the whole buffer to see the effect of bzero().
#include <strings.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
char s[11] = "Hello World";
bzero(s, 4);
for (int i = 0; i < 11; i++) printf("%d ", s[i]); // print elements of the buffer
puts(s);
return 0;
}
Output:
0 0 0 0 111 32 87 111 114 108 100
This question already has answers here:
What is going on with 'gets(stdin)' on the site coderbyte?
(3 answers)
Closed 3 years ago.
I just want to reverse the string order by switching the place of each index in the string.
#include <stdio.h>
#include <string.h>
void FirstReverse(char str[]) {
int a = strlen(str);
for(int i=0; i<strlen(str) ;i++){
str[i] = str[a-1];
a-=1;
}
}
int main(void) {
// keep this function call here
FirstReverse(gets(stdin));
return 0;
}
Error: "signal: segmentation fault (core dumped)"
There are multiple errors in your code. The obvious ones are that gets is used wrong (and, to be honest, that it is used at all) and it does not output the result in any way. But let's apply some quick fixes with minimal changes to your logic:
#include <stdio.h>
#include <string.h>
void FirstReverse(char str[]) {
int a = strlen(str);
for(int i=0; i<strlen(str) ;i++){
str[i] = str[a-1];
a-=1;
}
}
int main(void) {
char string[100]; // This is going to be our working field where the changes happen
fgets(string, 100, stdin); // read a line of up to 100 characters into "string"
FirstReverse(string); // do the work (this could be chained, like it was originally)
puts(string); // output the result
return 0;
}
Now it compiles and executes without failing but the result is wrong:
In: My favourite string
Out: gnirts ette string
What went wrong? Let's follow what happens step by step:
i a
↓ ↓
My favourite string
(program writes the last character [see point 3 below] in place of `M`)
↓ ↓
y favourite string
(program writes `g` in place of `y`)
↓ ↓
g favourite string
(program writes `n` in place of the space)
↓ ↓
gnfavourite string
(program writes `i` in place of `f`)
etc.
ia
↓↓
gnirts eite string
(program writes `t` in place of `i`)
ai
↓↓
gnirts ette string
(program writes `t` in place of `t`)
a i
↓ ↓
gnirts ette string
(program writes `e` in place of `e`)
etc.
Three problems here:
By rewriting a character from the start by another from the end, you're not doing swapping. You're just copying the data from the end to start (but surely, in reverse order). The original is lost.
You are actually going twice through, because by the time i reaches half of the interval, a keeps decreasing and they cross. Now i still needs to finish the loop and a continues towards the beginning of the string where you've already been. If you actually did swapping, you'd swap 1 with 2 and then later 2 with 1 again, resulting in the original unchanged!
(minor) A string returned by (f)gets ends with a newline character, so that becomes the beginning of your result. Probably not what you want, but has an easy fix of chopping that off before feeding the string to your function.
You'll need to deal with each of these, other answers by now contain some advice. But I thought it instructive to run your code and try to "think like the machine" in explaining why the computer misunderstands your intention. If you swap the letters by copying one in a temporary variable, then rewriting str[i], then writing back in str[a-1] from the temporary, and stop before i and a cross each other, you can see for yourself you'll take care of 1 and 2.
run only till mid of the string
keep in some var the overridden char in side the loop
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
void FirstReverse(char str[]) {
int a = strlen(str);
for (int i = 0; i <= a; ++i, --a) {
char c = str[i];
str[i] = str[a - 1];
str[a - 1] = c;
}
}
int main(void) {
// keep this function call here
char s[100] = { 0 };
scanf("%s",s);
FirstReverse(s);
printf("%s",s);
return 0;
}
Simple way to do it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * reverse(char *str)
{
size_t size = strlen(str);
char *res = malloc(size * sizeof(char));
for(size_t i=0; i<size; i++) {
res[i] = str[size-i-1];
}
return res;
}
int main(void)
{
printf("%s\n",reverse("Hello World"));
return 0;
}
Output : dlroW olleH
Instead of switching each char, just create a new string in which you copy the last char, then the last-1 and so on. You'll also prevent yourself from switching the same char if the length of your string is uneven ('\0' put aside).
I'm learning C with an old book "The C Programming Language" and experimenting with pointers at the moment.
#include <stdio.h>
int
main (void)
{
// init string
char s[8] = "ZZZZZZZ";
// it goes: Z Z Z Z Z Z Z \0
long *p; // make pointer refering to the same adress as s
p = s; // but declared long for modifying 4 bytes at once
*p = 0x41414141; // and assign hexadecimal constant equal to 65 65 65 65
// expect output to be: AAAAZZZ
printf ("%s\n", s);
// but get the next: AAAA
// wrote the following line to find out what's wrong with last 4 chars
printf ("%i%i%i%i\n", s[4], s[5], s[6], s[7]);
// and those appear to become zero after messing with first 4 ones
return 0;
}
So, the output is:
AAAA
0000
Why are the last 4 bytes zeroes?
P.S. already got the answer: type long is 8 bytes on x64 machine, and I am inobservant. Surprised what a good thing is StackOverflow. Thank you guys.
Your long is likely 64-bit large. It could work with a int32_t pointer (does on my PC):
#include <stdio.h>
#include <stdint.h>
int
main (void)
{
// init string
char s[8] = "ZZZZZZZ";
// it goes: Z Z Z Z Z Z Z \0
int32_t *p; // making pointer refering to the same adress as s
p = (int32_t*)s; // but declared as long for modifying 4 bytes at once
*p = 0x41414141; // and assign hexadecimal constant equal to 65 65 65 65
// expect output to be: AAAAZZZ
printf ("%s\n", s);
// but get the next: AAAA
// wrote the following line to find out what's wrong with last 4 chars
printf ("%i%i%i%i\n", s[4], s[5], s[6], s[7]);
// and those appear to become zero after messing with first 4 ones
return 0;
}
but strictly speaking, this type-punning is a strict-aliasing violation (which makes your program undefined). memcpy or char-by-char copying from the 32-bit integer, or unions (safest in case you decided to start allocating the objects dynamically), should do it reliably:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int
main (void)
{
// init string
char s[8] = "ZZZZZZZ";
// it goes: Z Z Z Z Z Z Z \0
int32_t src = 0x41414141;
memcpy(s, &src, sizeof(src));
// expect output to be: AAAAZZZ
printf ("%s\n", s);
// but get the next: AAAA
// wrote the following line to find out what's wrong with last 4 chars
printf ("%i%i%i%i\n", s[4], s[5], s[6], s[7]);
// and those appear to become zero after messing with first 4 ones
return 0;
}
you can try to put different values and you will see the architecture is little endian:
#include <stdio.h>
int main (void)
{
char s[8] = "ZZZZZZZ";
// it goes: Z Z Z Z Z Z Z \0
long *p;
p = (long *)s;
*p = 0x41424344; // A B C D
printf ("%s\n", s);
return 0;
}
result: DCBA
and the rest of the result is 0 because you assigned:
*p = 0x0000000041424344; // /0 /0 /0 /0 A B C D
I want to extract a number from an array I introduce in the keyboard and convert it into one integer. My code is:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int r, t, i;
char expressio[t];
char vector[50];
char rpn[t][4];
printf("Introduce the expresssion");
fgets(expressio, t, stdin);
t = strlen(expressio);
for (i = 0; i <= t; i++) {
if (isdigit(expressio[i])) {
r = atoi(expressio[i]);
vector[i] = rpn[0][r];
}
return 0;
}
}
I have this warning:
passing argument 1 of 'atoi' makes pointer from integer without a cast
How can i solve it?
Also, when I execute this program, it does nothing and it doesn't even print the "Introduce the expression". Why is this happening?
That warning means that you are passing a bad argument to the function. "atoi" is expecting an array of chars as argument, but you are passing a single char as argument here:
r = atoi(expressio[i]);
If you want to convert a single char into a number, you can do:
r = expressio[i] - '0';
If you look at the ascii table, you will notice that the ascii value of 0 is 48. If you substract 48 (or, like i did, the ascii value of 0) to your char expressio[i], you will get the corresponding number as an integer. Like this, if expressio[i] equals '8', then r will equal 8.
i am writing a basic c program to display two strings, one taken from user i.e "a" and the other being defined in code "b" but when i run the code below string "a" gets appended to "b". why? and what is that symbol at end of "a"
updated code:
#include <stdio.h>
#include <string.h>
int main()
{
char a[ 5 ];
int i=0;
while(i<5)
{
a[i]=getchar();
i++;
}
char b[]={'r','f','s','/0'};
printf("output:-");
printf("\n %s",a);
printf("\n %s",b);
return 0;
console
qwert
output:-qwert$
rfs$qwert$
there is a some special symbol instead of $ above, what is it?
Putting all the comments into an answer. The problems in the original code stem mostly from not NUL terminating the character arrays to produce valid C strings.
a is not NUL terminated. Can fix by increasing the a array by 1 and explicitly writing a NUL to the last byte.
b is not NUL terminated. Can fix by initialising b using a literal string or a char array with '\0' as the last byte. The example below uses the former.
Here is the full code with the errors corrected. Note that the code to read input is fragile as it only accepts exactly a 5 character string.
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[6];
int i=0;
while (i<5) {
a[i]=getchar();
i++;
}
a[i] = '\0';
char b[]="rfs";
printf("output:-\n");
printf(" %s\n",a);
printf(" %s\n",b);
return 0;
}