when I run this code I always found a problem in my IDE. Can you give this solution ?
#include<stdio.h>
#include<string.h>
int main(void)
{
char cname[4]="mahe";
strcat(cname, "Karim");
printf("%s",cname);
getch();
return 0;
}
Your array isn't big enough. The original array isn't big enough to hold the null byte at the end of its initial value, so strcat() can't find the end of the string. And then you're adding to it, which writes outside the array. These are both causing undefined behavior.
It needs to be declared large enough to hold the original string, the string you're adding to it, and the trailing null byte. So it has to be at least 10 bytes (4+5+1).
char cname[10] = "mahe";
strcat(cname, "Karim");
printf("%s\n", cname);
Change char cname[4] to char cname[10]. Because you are setting the size 4 and so, you can't append any more to it after adding 4 chars initially.
So, change the size. That's it
Related
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s1;
char *s2;
printf("Enter the string : ");
scanf("%s",s1);
printf("Enter the string : ");
scanf("%s",s2);
return 0;
}
I'm facing problems in taking inputs in char pointer. Here I'm just taking 1 word as input but Scanf isn't taking any inputs at all when using char pointer, but works well with char arrays. Is it a code blocks bug?
A pointer is a variable that holds a memory address.
An uninitialized variable contains (generally) some random garbage number.
When you pass some random garbage number to scanf and tell it to store a string at that address, it's no surprise that (usually) the program crashes.
It makes no sense to tell scanf to store a string at an address where you don't know what the address is. It's like telling your friend to come over to your house and when they ask which house is yours, you click somewhere random on Google Maps. It's probably going to be in the middle of the ocean or something and they'll drown.
What you need to do is make a space to put the string (such as by declaring an array) and then tell scanf to put the string in that space that you specifically made to hold the string.
A pointer to a string does not hold the string. A pointer to a string is just a signpost saying "the string is over there --->", and you can change it if you want it to point to a different place, maybe holding a different string, but it's never going to hold a string itself.
This is a beginner-C-programmers' bug as old as the language itself.
There are two good solutions to your problem, either change the definitions of s1 and s2 to something like
char s1[BUFFER_LENGTH];
char s2[BUFFER_LENGTH];
...where BUFFER_LENGTH-1 is some sufficiently long string length, to tell the compiler to allocate enough memory on the stack, or manually allocate memory in the heap for them using malloc() like so:
char *s1 = malloc(BUFFER_LENGTH);
char *s2 = malloc(BUFFER_LENGTH);
But keep in mind that in both cases your code is unsafe because for any finite-length buffer, there is a string too long for it, which can cause your program to crash or overwrite something important in memory or give hackers access to stuff etc. etc.
A safe solution is to allocate memory for your strings in one of the two above ways, and only read strings that are small enough to fit into them. If you require the program to be able to handle a string of any length, your code will be much more complex, but there's still a safe way to do it.
#include <stdio.h>
#define BUFFER_LENGTH 20 //Arbitrary max string length + 1
int main(){
char s1[BUFFER_LENGTH]; //Can safely hold 19 chars for string and a null terminator
char s2[BUFFER_LENGTH];
printf("Enter the string : ");
scanf("%19s",s1); //%19s tells the function to only read max 19 characters
printf("Enter the string : ");
scanf("%19s",s2);
{
In the above example a string longer than 19 characters will be truncated, for instance "012345678901234567890" will be stored in s1 as "0123456789012345678" and s2 will have "90" since scanf will just use the leftover characters in the input buffer for the next call.
Here's what I did:
#include <stdio.h>
#include <string.h>
int main() {
char name[] = "longname";
printf("Name = %s \n",name);
strcpy(name,"evenlongername");
printf("Name = %s \n",name);
printf("size of the array is : %d",sizeof(name));
return 0;
}
It works, but how? I thought that once memory is assigned to an array in a program, it is not possible to change it. But, the output of this program is:
Name = longname
Name = evenlongername
size of the array is 9
So the compiler affirms that the size of the array is still 9. How is it able to store the word 'evenlongername' which has a size of 15 bytes (including the string terminator)?
In this case, name is allocated to fit "longname", which is 9 bytes. When you copy "evenlongername" into it, you're writing outside of bounds of that array. It's undefined behavior to write outside of the bounds, this means it may or may not work. Some times, it'll work, other times you'll get seg fault, yet other times you'll get weird behavior.
So the compiler affirms that the size of the array is still 9. How is it able to store the word 'evenlongername' which has a size of 15 bytes(including the string terminator)?
You are using a dangerous function (see Bugs), strcpy, which blindly copies source string to destination buffer without knowing about its size; in your case of copying 15 bytes into a buffer with size 9 bytes, essentially you have overflown. Your program may work fine if the memory access is valid and it doesn't overwrite something important.
Because C is a lower-level programming language, a C char[] is "barebone" mapping of memory, and not a "smart" container like C++ std::vector which automatically manages its size for you as you dynamically add and remove elements. If you are still not clear about the philosophy of C in this, I'd recommend you read *YOU* are full of bullshit. Very classic and rewarding.
Using sizeof on a char array will return the size of the buffer, not the length of the null-terminated string in the buffer. If you use strcpy to try and overflow the array, and it just happens to work (it's still undefined behavior), sizeof is still going to report the size used at declaration. That never changes.
If what you're interested in is observing how the length of a string changes with different assignments:
Use an adequate buffer to store every string you're going to test.
Use the function strlen in <string.h> which will give you the actual length of the string, and not the length of your buffer, which, once declared, is constant.
I am trying to test something and I made a small test file to do so. The code is:
void main(){
int i = 0;
char array1 [3];
array1[0] = 'a';
array1[1] = 'b';
array1[2] = 'c';
printf("%s", array1[i+1]);
printf("%d", i);
}
I receive a segmentation error when I compile and try to run. Please let me know what my issue is.
Please let me know what my issue is. ? firstly char array1[3]; is not null terminated as there is no enough space to put '\0' at the end of array1. To avoid this undefined behavior increase the size of array1.
Secondly, array1[i+1] is a single char not string, so use %c instead of %s as
printf("%c", array1[i+1]);
I suggest you get yourself a good book/video series on C. It's not a language that's fun to pick up out of the blue.
Regardless, your problem here is that you haven't formed a correct string. In C, a string is a pointer to the start of a contiguous region of memory that happens to be filled with characters. There is no data whatsoever stored about it's size or any other characteristics. Only where it starts and what it is. Therefore you must provide information as to when the string ends explicitly. This is done by having the very last character in a string be set to the so called null character (in C represented by the escape sequence '\0'.
This implies that any string must be one character longer than the content you want it to hold. You should also never be setting up a string manually like this. Use a library function like strlcpy to do it. It will automatically add in a null character, even if your array is too small (by truncating the string). Alternatively you can statically create a literal string like this:
char array[] = "abc";
It will automatically be null terminated and be of size 4.
Strings need to have a NUL terminator, and you don't have one, nor is there room for one.
The solution is to add one more character:
char array1[4];
// ...
array1[3] = 0;
Also you're asking to print a string but supplying a character instead. You need to supply the whole buffer:
printf("%s", array1);
Then you're fine.
Spend the time to learn about how C strings work, in particular about the requirement for the terminator, as buffer overflow bugs are no joke.
When printf sees a "%s" specifier in the formatting string, it expects a char* as the corresponding argument, but you passed a char value of the array1[i+1] expression. That char got promoted to int but that is still incompatible with char *, And even if it was it has no chance to be a valid pointer to any meaningful character string...
So I'm working on a program to take in assembly code in a text file and produce the corresponding machine code. However, I'm running into an issue when I'm trying trying to assign values to the members of the AssemblyLine struct. What happens is that when ".fill" is the opcode, arg0 is concatenated to it, and there are also issues with arg0 if I assign value to arg0 first. It is important to note that this only happens when the opcode is ".fill". For example, if the opcode is "add" the values are what I intended for them to be.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct AssemblyLine {
char opcode[5];
char arg0[7];
char arg1[7];
char arg2[7];
_Bool initialized;
};
struct Label {
char name[7];
int address;
_Bool initialized;
};
main()
{
struct AssemblyLine line;
strcpy(line.opcode, ".fill");
strcpy(line.arg0, "5");
printf("%s\n", line.opcode);
return 0;
}
The output for this program is:
.fill5
My intention is that the output would just be:
.fill
I'm really confused about what would be causing this. Sorry if the answer is really obvious, this is my first time working in C, though I have programmed in C++ before. I was at first thinking that there was no null terminating character, but the string is read fine until after I use the second strcpy. Is fill used as a key word for strcpy or something? I thought maybe it had to do with the '.' but that didn't affect anything when the opcode was ".lw".
Sorry that this post is so long! Thanks for any help!
Your array isn't big enough. ".fill" is six characters include the terminating null, but you only allocate memory for five with char opcode[5]. You need to make your array bigger.
The string ".fill" is 5 characters + 1 zero character long. That makes 6 characters.
But the array 'opcode' is only 5 characters long, so the trailing zero is written to 'arg0'.
After that, your copy "5" (2 characters with zero) to 'arg0'.
Because 'printf' prints until the trailing zero occurs, it reads out of the bounds of opcode.
In the below example when I define char array uninitialized and want to find the length, it's undefined behavior.
#include<stdio.h>
int main()
{
char a[250];
printf("length=%d\n",strlen(a));
}
I got "0". I don't know how? Explain it.
Luck. Whether it's good or bad luck is a matter of opinion. The contents of your array are whatever happened to already occupy that memory, and is not initialized. In your case, it happened the first byte was a '\0'.
This is, of course, undefined behavior and you can't depend on it happening this way.
You said in your example you were using an uninitialized char array to show undefined behavior, then when you got "0" you want an explanation? It's... undefined behavior.
If you got 0 for the length if just means that there happens to be a 0 as the first element of a[] in your uninitialized array. When it's an uninitialized local that means, as far as the C standards are concerened, anything can be in there, including a 0.
To address the question in your title: "Is it necessary to initialize the char array for accurate length?"
Yes, to be able to deterministically know the length of a string in a char array via the strlen() function, it is required for a null terminator to be present. That means it needs to be initialized or set in some manner or another.
As other answers say the strlen() result is more a matter of luck than defined behaviour
To find the "size" of the memory block use sizeof() instead
Note: I've also included the string.h and used a long conversion for the integers in the printf
#include<stdio.h>
#include<string.h>
int main()
{
char a[250];
printf("length=%ld\n",strlen(a));
printf("sizeof=%ld\n",sizeof(a));
}
when you define
char a[250];
The array will contains garabage contents and random.
strlen(a) count the number of not null charachter ('\0') till it find a null charachter then it stop.
so if your char a[250]; array contains garabage element and the first element is randomly set to null '\0' the strlen(a) will return 0