# include <stdio.h>
int main(void)
{
char a[]="0123456789";
char b[5];
a[5]='\0';
char *c=a;
for(int i=0,j=sizeof(b)/sizeof(char);i<j;i++){
*(b+i)=*(c+(7*i));
}
printf("%d\n", sizeof(a)/sizeof(char));
printf("%s\n", a);
printf("%s\n", b);
printf("%c\n", *(b+3));
return 0;
}
There is no one output in this code
4 outputs are needed but one output is missing and I don't know why it happens and how to solve this problem
Let me walk you through what is happening.
I've modified your code slightly to make it easier to read
#include <stdio.h>
int main(void)
{
char a[]="0123456789"; //a is 11 chars long [0,1,2,3,4,5,6,7,8,9,\0]
char b[5]; //b is 5 chars long and we don't know what's in it
a[5]='\0'; //a now looks like this [0,1,2,3,4,\0,6,7,8,9,\0]
char *c=a; //c points to a
for(int i=0; i < sizeof b / sizeof(char); i++){ //j is unnecessary here
b[i] = c[7 * i]; //This is equivalent to your code and is easier to read
}
//If the program hasn't crashed, b now looks like this [0,7,?,?,?]
//(where ? means it could be anything at all)
printf("%zd\n", sizeof a /sizeof(char)); //We expect 11 to print (%zd is for size_t)
printf("%s\n", a); //Strings end at \0 so we expect "01234"
printf("%s\n", b); //We expect "07..." but we have no idea what comes next
printf("%c\n", b[3]); //This could do anything
return 0;
}
In your for loop, you initialize the 5-character array b with c[0], c[7], c[14], c[21], and c[28].
You initialized c by pointing it to a, so c[0] is the same as a[0], c[7] is the same as a[7] etc.
Since a is only 11 characters long, we can be certain that b[0] = '0' and b[1] = '7' but after that we've invoked undefined behavior and we have no idea what will happen. It is entirely possible that the program will crash after printing...
11
01234
07
or it could do something completely unexpected.
Related
I've got this tiny program I wrote for a C pointers exercise. I simply take a char array and print it in reverse using a pointer. It works. However, I don't understand why it works. Since I'm starting the for loop at element 9, shouldn't it print 5 undefined elements (usually random junk characters, in my experience) before it gets to the "sdrow"? I feel like I should be filtering the output more.
int main(void)
{
char sentence[10] = "words";
char *ptr = sentence;
for(int i=9;i>=0;i--)
{
printf("%c", *(ptr+i));
}
puts("");
return 0;
}
Output:
sdrow
When you initialize an array and the initializer provides fewer elements than there are in the array, the remaining elements are initialized to zero:
int a[3] = { 1 }; // same as { 1, 0, 0 }
char s[4] = "ab"; // same as { 'a', 'b', 0, 0 }
In other words, your code is printing five null bytes before printing the five letters.
(You can see this easily by redirecting the output to a file and looking at the file size.)
When you initialize an array of fixed size, c will automatically fill any unspecified elements with zeros. C-style strings treat these zeros as the null character, which is also the string termination character.
So the first bunch of iterations print a null character, then they start printing actual characters.
The rest of the array is initialized by the compiler with zeroes, it's why you see nothing:
int main(void)
{
char sentence[10] = "words";
char *ptr = sentence;
for(int i=9;i>=0;i--)
{
printf("%02x", *(ptr+i));
}
puts("");
return 0;
}
However you should not rely on this, since the behavior is undefined. If you were using pointers, you would see something different:
int main(void)
{
char *sentence = "words";
char *other ="more";
char *ptr = sentence;
for(int i=9;i>=0;i--)
{
printf("%c", *(ptr+i));
}
puts("");
return 0;
}
I got a homework question. I'm so close to complete program. I'm having trouble about one thing. This is the question:
Write a C program that generates and displays a character array of size 10 consisting of
random English lower-case letters. The program then asks the user how many times the array
will be right-shifted and displays the right shifted array at each right-shifting step. A sample
program execution output is given below. ( Hint: Use the ASCII codes of the English lower-case
letters which are 97, 98, ... 122 for a, b, ..., z, respectively, to generate the character array).
This is my code:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
void print_string (char *string){
int i;
for (i=0 ; i < 10 ; i ++){
printf("%c ", string[i]);
if (i == 9)
printf("\n");
}
}
void random_string(char *string, unsigned length)
{
/* Seed number for rand() */
srand((unsigned int) time(0) + getpid());
/* ASCII characters 97 to 122 */
int i;
for (i = 0; i < length; ++i)
{
string[i] = (rand() % 26)+ 97;
}
string[i] = '\0';
}
void reverse_string(char* str, int left, int right) {
char* p1 = str + left;
char* p2 = str + right;
while (p1 < p2) {
char temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2--;
}
}
void rotate(char* str, int k, int n) {
reverse_string(str, 0, n-1);
reverse_string(str, 0, k-1);
reverse_string(str, k, n-1);
}
int main(void)
{
char s[11];
int i,shiftNum;
random_string(s, 11);
printf("Randomly constructed array is :\n");
print_string(s);
printf("Enter how many times array will be shifted: ");
scanf("%d",&shiftNum);
rotate(s,shiftNum,11);
print_string(s);
}
What's wrong with this code? When I execute it with 1, I couldn't get the first reverse correctly and I want to display all shifting steps.
For a start, it is atrocious that your lecturer/professor is telling you to use 97..122. C does not require that ASCII be the character set on every system, so this code is entirely non-portable, yet if you look at the history as far as Unix is concerned C is supposed to be a portable programming language. If you want to write this in a portable way, you need to store the characters in an array and select from that array:
char lowercase[] = "abcdefghijklmnopqrstuvwxyz";
string[i] = lowercase[rand() % (sizeof lowercase - 1)];
Now that we've covered that pedantic detail, Cool Guy indicated in a comment that this line of code is erroneous: string[i] = '\0';. He's correct about that.
This should also performed within main, not within random_string: srand((unsigned int) time(0) + getpid());. The reason is that calling random_string multiple times in the same second would result in the same "random string", which is very uncool.
scanf("%d",&shiftNum); can't guarantee success (that the user will input numeric data), and so can't guarantee that shiftNum will contain a sane value. You need to check the return value. For example:
if (scanf("%d", &shiftNum) != 1) {
puts("Invalid shift count!\n");
exit(0);
}
You should probably also consider using an unsigned type for shiftNum (and this will cause the corresponding format spec %d to change to something else, such as %u for unsigned int).
One more important task before I finish this task: You need to modify rotate to handle an input of 0 correctly, since some users might want to rotate/shift 0 times (as an alternative to not rotating/shifting at all). I'm confident that this should be an easy task for you.
I want know how integers are treated in char arrays. For example when we use scanf() & printf() functions for single characters we use "%c", for string values "%s", etc. I used "%s" for printing the char array with integers. But it prints some junk characters as the output.
While working with integer variables directly, it's simple as:
int i = 7;
printf("%d", i);
and while working with an array of characters, you could create helper functions that will do the conversion between char* <-> int so that you end up with more portable solution:
int toInt(unsigned char* p) {
return *(p + 0) << 24 | *(p + 1) << 16 | *(p + 2) << 8 | *(p + 3);
}
...
unsigned char arr[4] = {0,0,0,4};
int i = toInt(&arr[0]);
printf("%d", i);
should print 4
Alternatively you might use simple cast:
unsigned char arr[4] = {0,0,0,4};
int* i = &arr[0];
printf("%d", *i);
but that solution will be depend on endianness. On ideone.com it prints 67108864.
If you know the length of each phone number will be the same, you could pad out the front of the number with zeros. e.g. to pad each number out to 10 digits, putting 0's in front when necessary:
int d = 123456789;
printf("%d\n", d); // prints 123456789
printf("%010d\n", d); // prints 0123456789
d = 12345678;
printf("%010d\n", d); // prints 0012345678 :-(
It's hard to guess more about the requirements without seeing the code. There's lots of examples of formatting with printf, eg: http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output
int main()
{
unsigned char a[3];
unsigned char (*p)[3]=NULL;
unsigned char *q=NULL;
int i = 0;
a[0]=0;
a[1]=1;
a[2]=2;
p=&a;
for(i=0;i<3;i++){
if((*p)[3] == a[3]){
printf("*p[%d]:%d a[%d]:%d",i,(*p)[3],i,a[3]);
}
}
}
o/p:
*p[0]:0 a[0]:0*p[1]:0 a[1]:0*p[2]:0 a[2]:0
Exited: ExitFailure 14
I want to copy an array of size 3 to a pointer and to do a comparision. I have written a sample program. But i'm getting an error value.
I ran this using an online c compiler . (codepad.org)
Please help me in identifying my mistakes.
Your variable p is an array, not a pointer. You can't re-assign an array to point somewhere else, so the line
p = &a;
is not valid.
Also, C indexes from 0 as you seem to know, so comparisons using index [3] for arrays of size 3 are not valid.
Further, in your comparison loop you're not actually using i to index, but instead always comparing using the invalid constant index [3].
It's not very clear from your code (q is not used, for instance), but it sounds as if you want to do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char a[3];
unsigned char *p;
p = malloc(sizeof a);
if(p != NULL) /* If allocation succeeded, p is valid. */
{
int i;
memcpy(p, a, sizeof a);
for(i = 0; i < sizeof a; ++i)
{
if(p[i] == a[i])
printf("p[%d]:%d a[%d]:%d\n", i, p[i], i, a[i]);
}
free(p);
}
Of course, this will always print all the numbers, since memcpy() will never fail to copy the memory. :)
Here You have declared the return type of main function as int, but you are not returning anything from it.
So return any integer value (like 1) or make the main function's return type void.
I am writing the memset function and my code is below, I am having a problem
void* memsetFun(void* pointer, int c, int size) {
if ( pointer != NULL && size > 0 ) {
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
}
}
return pointer;
}
I also tried pChar[i] = the value we want and still not working. It gives me some trash numbers that do not make any sense.
And I am calling it:
memsetFun(address, num, size);
printf("value at %p is %d\n", address, *((int*) address));
Where I call the address (I just input the address)
For example, if you to print the chars ( c ) it prints like a weird char that looks like ( for the value 4 )
0 0
0 4
Your code looks fine to me and several people here have commented that it works on their system.
So the obvious thing to do is to debug it - that's a skill that will come in handy quite a bit in future :-) You should learn it now.
What does the following code output when you run it?
void* memsetFun(void* pointer, int c, int size) {
printf("A %x %d %d\n", pointer, c, size);
if ( pointer != NULL && size > 0 ) {
printf("B\n");
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
printf("C %d (%d)", i, *pChar);
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
printf(" -> (%d)", i, *(pChar-1));
}
}
printf("D\n");
return pointer;
}
From the output, it should be clear what paths the code is taking and what your parameters are (which will greatly assist the debugging process).
Update:
If you're filling your memory block with anything other than zeros and using this:
printf("value at %p is %d\n", address, *((int*) address));
to print it out, you will get strange results.
You're basically asking for a number of those bytes to be interpreted as an integer. So, for example, if you filled it with 0x02 bytes and you have a 4-byte integer type, you will get the integer 0x02020202 (33686018), not 0x02 as you may expect. If you want to see what the first character value is, use:
printf("value at %p is %d\n", address, *((char*) address));
And based on your latest question update:
For example, if you to print the chars ( c ) it prints like a weird char that looks like ( for the value 4 )
0 0
0 4
If that's a single character and you're printing it as a character, there's probably nothing wrong at all. Many output streams will give you that for a control character (CTRL-D in this case, ASCII code 4). If you instead filled it with ASCII code 0x30 (48), you would see the character '0' or ASCII 0x41 (65) would give you 'A'.
As pointed out already, your function works as it should. Here is a complete example:
#include <assert.h>
#include <string.h>
void* memsetFun(void* pointer, int c, int size) {
if ( pointer != NULL && size > 0 ) {
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
}
}
return pointer;
}
int main() {
// Your memset
char a[10];
memsetFun(a, 'A', sizeof(a));
// Uses system memset for verification
char b[10];
memset(b, 'A', sizeof(b));
assert(sizeof(a) == sizeof(b));
assert(memcmp(a, b, sizeof(b)) == 0);
return 0;
}
return p; prevents this from compiling: p is not defined.
A minor efficiency issue—in practice it would have little effect, since any good compiler would rearrange it, but coding perfectionists wouldn't allow it to remain—the assignment to temp is inside the loop, but it is the same assignment every time. That is, the assignment to temp can be moved before the loop.
You return p, which isn't defined/doesn't point to anything in particular. Maybe you meant pointer?
The code is logically correct. With the p => pointer change it works correctly.
Clarify how exactly it is "not working". Perhaps you are not understanding what it is supposed to do?
You are probably getting trash numbers because you are casting from an int (4 bytes) to an unsigned char (1 byte), so if c > 255 or < 0 you won't be memsetting the values you are expecting to be.
I ran a test if your program setting the memory of an int vector of 5 elements setting with the value 0x01.
The problem here is that you are iterating in a vector of int for example (which is 4 bytes) but iterating over it using char pointer arithmetic (1 byte). If you want to memset 0x01 for example you will write this number per value in the vector: 00000001000000010000000100000001
which gives me the same value using the original memset.
Your function, as is, works for me.
I suppose you're calling it wrong. I call it like this
char a[100];
memsetFun(a, 0, sizeof a);
int b[100];
memsetFun(b, 0, sizeof b);
How are you calling your memsetFun()?
Edit
With
int b[100];
memsetFun(b, 9, sizeof b);
as an int is made up of 4 bytes (on my system) each value will be set to 0x09090909 or 151587081.
That is exactly what it's supposed to do. Your function is working perfectly fine. The value "0x4" is not the ASCII character '4'.