1

I'm trying to learn some of the basics of C and I have been reading nonstop about gets/fgets/puts/scanf and can't seem to get this right...

My code is:

#include <string.h>
#include <stdio.h>
#define BUFF 256

void main()
{

char s[BUFF];
fgets(s, BUFF, stdin);
s[strlen(s)-1]='\0';
printf("%x %s %d", s, s, strlen(s));
}   

I'm trying to get the hex format of the variable s to print, my input is AAAA and the output I want is 41414141 AAAA 4, the output I'm getting is 12fe80 AAAA 4.

I thought I needed to cast s (as a u int) for the hex interpretation, but that didn't work either.

I would really appreciate an explanation on this as well as help, I'm really trying to learn this.

Thank you!

0

6 Answers 6

2
void main()

This isn't your problem, but the correct definition is

int main(void)

void main() is useful mostly as a tool to detect C textbooks written by incompetent authors.

printf("%x %s %d", s, s, strlen(s));

This has undefined behavior:

  • "%x" requires an argument of type unsigned int; you're giving it a char* (the array expression s is converted to a pointer to its first element).
  • %d requires an argument of type int; you're giving it a size_t. Either convert it to int, or use %zu.

If you want to print a hexadecimal representation of the contents of the string s, there's no direct way to do that. You'll just have to loop over the characters contained in s and print the value of each one in hexadecimal. (You should cast each char value to unsigned int so it works properly with the "%02x" format.)

Sign up to request clarification or add additional context in comments.

Comments

2

%x works on numbers. You're passing in a pointer to a string. So in this case printf() is interpreting the pointer (memory address) as a number and printing that address in hex format. Sounds like you just want to print the ASCII values, in hex, of each character in the input:

for (int i = 0; i < strlen(s); ++i)
    printf("%02x", (unsigned) s[i]);

1 Comment

@dasblinkenlight You're right, I didn't think through the - 1. Will remove that comment, thanks.
1

Try this

$ cat hello.c
#include <string.h>
#include <stdio.h>
#define BUFF 256

int main()
{
  int i = 0;              /* a counter */
  char s[BUFF];
  fgets(s, BUFF, stdin);
  s[strlen(s)-1]='\0';
  while (i < strlen(s)) { /* to get the character(s) in s */
    printf("%x", s[i]);   /* as hex */
    i++;
  }
  printf(" %s %d\n", s, strlen(s)); /* as before */
}
$ gcc hello.c -o hello && echo "AAAA" | ./hello
41414141 AAAA 4

Comments

1

The hex value you are printing is the address of the string, not the contents (since s is a char*).

To see the full contents of the string as hex bytes, you will have to do something like this:

int n = strlen(s);
for(int ii=0; ii<n; ii++) printf("%02x", (unsigned int) s[ii]);

4 Comments

Your first printf has undefined behavior. How do you know that the first sizeof (int) bytes of s are correctly aligned? What about byte order? %x requires an unsigned int, not an int. %d requires an int; strlen() returns a size_t result. (Yes, I downvoted.)
@KeithThompson I appreciate your inputs. I have updated my answer.
I'm saying no compiler, regardless of how modern it is, is required to cope with badly aligned pointers. (x86 happens to handle misaligned addresses in hardware; other platforms require strict alignment). The point is that your first printf has undefined behavior, and IMHO is poor style as well. And I see you deleted it from your answer as I was writing this, so I'll withdraw the downvote. But you're computing strlen(s) on every iteration of the loop, which is inefficient.
@KeithThompson - I guess I have never used a platform that had trouble with misaligned pointers, but I see your point. And I've eliminated the "gross inefficiency" in the loop.
0
#include <stdio.h>
#include <string.h>

main() {

    char a[]="AAAA";
    printf("%x%x%x%x %s %d", a[0],a[1],a[2],a[3],a, (int)strlen(a));
}

Comments

0

print all the array index one by one.

printf("%x ", *s);
printf("%x ", *(s+1));
....
....

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.