I have a C library that requires hexadecimal input of the form "\xFF". I need to pass an array of hexadecimal values formatted as "0xFF" form. Is there a way to replace "0x" by "\x" in C?
That sounds like an easy string replacement operation, but I think that's not really what you need.
The notation "\xFF" in a C string means "this string contains the character whose encoded value is 0xFF, i.e. 255 decimal".
So if that's what you mean, then you need to do the compiler's job and replace the incoming "0xFF" text with the single character that has the code 0xFF.
There is no standard function for this, since it's typically done by the compiler.
To implement this, I would write a loop that looks for 0x, and every time it's found, use strtoul() to attempt to convert a number at that location. If the number is too long (i.e. 0xDEAD) you need to figure out how to handle that.
You can use strstr in order to find the substring "0x" and then replace '0' with '\\':
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "0x01,0x0a,0x0f";
char *p = s;
printf("%s\n", s);
while (p) {
p = strstr(p, "0x");
if (p) *p = '\\';
}
printf("%s\n", s);
return 0;
}
Output:
0x01,0x0a,0x0f
\x01,\x0a,\x0f
But as pointed out by #unwind and #Sathish, that's probably not what you need.
Related
char buf1[1024] = "771675175\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
char buf2[1024] = "771675175\x00";
char buf3[1024] = "771675175\0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
char buf4[1024] = "771675175\0";
char buf5[1024] = "771675175";
buf5[9] = 0;
char buf6[1024] = "771675175";
buf6[9] = 0;
buf6[10] = "A";
printf("%d\n", strlen(buf1));
printf("%d\n", strlen(buf2));
printf("%d\n", strlen(buf3));
printf("%d\n", strlen(buf4));
printf("%d\n", strlen(buf5));
printf("%d\n", strlen(buf6));
if("\0" == "\x00"){
printf("YES!");
}
Output:
10
9
9
9
9
9
YES!
As shown above, I use the "\x00" to interrupt a string.
As far as I know, when the strlen() meet the "\x00", it will return the number of characters before the terminator, and does not include the "\x00".
But here, why is the length of the buf1 equal to 10?
As pointed out in the comments section, hexadecimal escape sequences have no length limit and terminate at the first character that is not a valid hexadecimal digit. All of the subsequent A characters are valid hexadecimal digits, so they are part of the escape sequence. Therefore, the result of the escape sequence does not fit in a char, so the result is unspecified.
You should change
char buf1[1024] = "771675175\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
to:
char buf1[1024] = "771675175\x00" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
Also, strlen returns a value of type size_t. The correct printf format specifier for size_t is %zu, not %d. Even if %d works on your platform, it may fail on other platforms.
The following program will print the desired result of 9:
#include <stdio.h>
#include <string.h>
int main( void )
{
char buf1[1024] = "771675175\x00" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
printf( "%zu\n", strlen(buf1) );
}
Also, it is worth nothing that the following line does not make sense:
if("\0" == "\x00")
In that if condition, you are comparing the addresses of two pointers, which point to string literals. It depends on the compiler whether it is storing both string literals in the same memory location. Some compilers may merge identical string literals into the same memory location, some may not. Normally, this is irrelevant to the programmer. Therefore, it does not make much sense to compare these memory addresses.
You probably wanted to write the following instead, which will compare the actual character values:
if( '\0' == '\x00' )
There is a big difference between a string literal and a character constant.
I have just started learning C after coding for some while in Java and Python.
I was wondering how I could "validate" a string input (if it stands in a certain criteria) and I stumbled upon the sscanf() function.
I had the impression that it acts kind of similarly to regular expressions, however I didn't quite manage to tell how I can create rather complex queries with it.
For example, lets say I have the following string:
char str[]={"Santa-monica 123"}
I want to use sscanf() to check if the string has only letters, numbers and dashes in it.
Could someone please elaborate?
The fact that sscanf allows something that looks a bit like a character class by no means implies that it is anything at all like a regular expression library. In fact, Posix doesn't even require the scanf functions to accept character ranges inside character classes, although I suspect that it will work fine on any implementation you will run into.
But the scanning problem you have does not require regular expressions, either. All you need is a repeated character class match, and sscanf can certainly do that:
#include <stdbool.h>
bool check_string(const char* s) {
int n = 0;
sscanf(s, "%*[-a-zA-Z0-9]%n", &n);
return s[n] == 0;
}
The idea behind that scanf format is that the first conversion will match and discard the longest initial sequence consisting of valid characters. (It might fail if the first character is invalid. Thanks to #chux for pointing that out.) If it succeeds, it will then set n to the current scan point, which is the offset of the next character. If the next character is a NUL, then all the characters were good. (This version returns OK for the empty string, since it contains no illegal characters. If you want the empty string to fail, change the return condition to return n && s[n] == 0;)
You could also do this with the standard regex library (or any more sophisticated library, if you prefer, but the Posix library is usually available without additional work). This requires a little bit more code in order to compile the regular expression. For efficiency, the following attempts to compile the regex only once, but for simplicity I left out the synchronization to avoid data races during initialization, so don't use this in a multithreaded application.
#include <regex.h>
#include <stdbool.h>
bool check_string(const char* s) {
static regex_t* re_ptr = NULL;
static regex_t re;
if (!re_ptr) regcomp((re_ptr = &re), "^[[:alnum:]-]*$", REG_EXTENDED);
return regexec(re_ptr, s, 0, NULL, 0) == 0;
}
I want to use sscanf() to check if the string has only letters, numbers and dashes in it.
Variation of #rici good answer.
Create a scanset for letters, numbers and dashes.
//v The * indicates to scan, but not save the result.
// v Dash (or minus sign), best to list first.
"%*[-0-9A-Za-z]"
// ^^^^^^ Letters a-z, both cases
// ^^^ Digits
Use "%n" to detect how far the scan went.
Now we can use determine if
Scanning stop due to a null character (the whole string is valid)
Scanning stop due to an invalid character
int n = 0;
sscanf(str, "%*[-0-9A-Za-z]%n", &n);
bool success = (str[n] == '\0');
sscanf does not have this functionality, the argument you are referring to is a format specifier and not used for validation. see here: https://www.tutorialspoint.com/c_standard_library/c_function_sscanf.htm
as also mentioned sscanf is for a different job. for more in formation see this link. You can loop over string using isalpha and isdigit to check if chars in string are digits and alphabetic characters or no.
char str[]={"Santa-monica 123"}
for (int i = 0; str[i] != '\0'; i++)
{
if ((!isalpha(str[i])) && (!isdigit(str[i])) && (str[i] != '-'))
printf("wrong character %c", str[i]);//this will be printed for spaces too
}
I want to ... check if the string has only letters, numbers and dashes in it.
In C that's traditionally done with isalnum(3) and friends.
bool valid( const char str[] ) {
for( const char *p = str; p < str + strlen(str); p++ ) {
if( ! (isalnum(*p) || *p == '-') )
return false;
}
return true;
}
You can also use your friendly neighborhood regex(3), but you'll find that requires a surprising amount of code for a simple scan.
After retrieving value on sscanf(), you may use regular expression to validate the value.
Please see Regular Expression ic C
I would like to receive an integer x via user input, and return a string with length x in '#'s.
i.e.
x = 4
⇒ "####"
Is a simple solution possible, along the lines of:
printf( "%c * x = %c", hash, x, hash*x);
Currently, my online findings have me creating an iterative program:
#include <stdio.h>
#include <string.h>
//function creates xhash with width '#' characters
void append( char* xhash, char hash, int x )
{
int i = 0;
for ( i = 0; i < x; i++ ) { xhash[i] = hash; }
xhash[x] = '\0';
}
int main ( void )
{
int x = 0;
scanf( "%d", &x );
char xhash[250] = "";
char hash = "#";
append( xhash, hash, x );
printf( "%c", xhash );
return 0;
}
And this gives me a strange design: ▒
I find C strings very confusing, coming from Python where I would use
str.append(i)
or
str = "#" * x
C does not have a full-fledged string data type. "C strings" are just contiguous sequences if char values, terminated by a character with value 0 (which can be spelled '\0').
Very important to your question, though, is that (1) char is an integer data type, (2) different delimiters are used for string literals than for (single-)char literals, and (3) string literals evaluate to pointers to the first character of a C string.
Thus, this ...
char hash = "#";
... attempts to store a pointer in hash, probably resulting in the last byte of the pointer value. Instead, you want this:
char hash = '#';
Moreover, to print a C string via one of the printf()-family functions, you want to use edit descriptor %s:
printf("%s", xhash);
Descriptor %c is for outputting a single character.
A string in C is just an array of bytes followed by a zero byte. That is all that they are.
For a function that creates a string you have two options. You can have the caller pass in a pointer to an array (and the array size, if you're smart) and the function fills it in. The second option is to malloc inside your function and return the pointer to the caller.
Another thing to remember is the standard C library. Your append function is essentially memset followed by setting a zero at the end. You should just call memset instead of doing your own loop.
And I think you are getting weird output because the printf format for a string is %s not %c. The %c format is for a single character.
Finally if you are unfamiliar with C programming you should be compiling will all warnings turned on. The compiler warnings would have told you about the bad printf format string and the invalid char assignment.
I want to replace all 'a' characters from a string in ANSI C. Here's my code:
#include <stdio.h>
#include <stdlib.h>
void sos(char *dst){
while(*dst){
if(*dst == 'a')
*dst = '\0';
dst++;
}
}
int main(void){
char str[20] = "pasternak";
sos(str);
printf("str2 = %s \n", str);
return 0;
}
When I run it, result is:
str2 = p
But it should be
str2 = psternk
It works fine with other characters like 'b' etc. I tried to assign NULL to *dst, but I got error during compile.
How can I remove 'a' characters now?
In C, strings are zero-terminated, it means that when there's a '\0' in the string it is the end of the string.
So what you're doing is spliting the string in 3 different ones:
p
stern
k
If you want to delete the a you must move all the characters after the a one position.
What printf does is: read bytes until a '\0' is found.
You transformed "pasternak" to "p\0astern\0k", so printf prints p.
This convention is used on the string functions of the stdlib so that you don't have to pass string length as an argument.
This is why it is said that in C strings are null terminated: it is just a convention followed by the C stdlib.
The downside, as you discovered, is that strings cannot contain \0.
If you really want to print a given number of bytes, use something like fwrite, which counts the number of bytes to be printed, so it can print a \0.
The answers previously provided are perfect to explain why your code does not work. But you can try to use strtok to split the string based on the 'a' characters, to then join the parts together or simply print them appart. Check this example: http://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
'\0' is how the C language tools recognize the end of the string. In order to actually remove a character, you'll need to shift all of the subsequent characters forward.
void sos(char *dst) {
int offset = 0;
do {
while (dst[offset] == 'a') ++offset;
*dst = dst[offset];
} while (*dst++);
}
Suppose i have array of characters. say char x[100]
Now, i take input from the user and store it in the char array. The user input is less than 100 characters. Now, if i want to do some operation on the valid values, how do i find how many valid values are there in the char array. Is there a C function or some way to find the actual length of valid values which will be less than 100 in this case.
Yes, C has function strlen() (from string.h), which gives you number of characters in char array. How does it know this? By definition, every C "string" must end with the null character. If it does not, you have no way of knowing how long the string is or with other words, values of which memory locations of the array are actually "useful" and which are just some dump. Knowing this, sizeof(your_string) returns the size of the array (in bytes) and NOT length of the string.
Luckily, most C library string functions that create "strings" or read input and store it into a char array will automatically attach null character at the end to terminate the "string". Some do not (for example strncpy() ). Be sure to read their descriptions carefully.
Also, take notice that this means that the buffer supplied must be at least one character longer than the specified input length. So, in your case, you must actually supply char array of length 101 to read in 100 characters (the difference of one byte is for the null character).
Example usage:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *string = "Hello World";
printf("%lu\n", (unsigned long)strlen(string));
return 0;
}
strlen() is defined as:
size_t strlen(const char * str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
As you see, the end of a string is found by searching for the first null character in the array.
That depends on entirely where you got the input. Most likely strlen will do the trick.
Every time you enter a string in array in ends with a null character. You just have to find where is the null character in array.
You can do this manually otherwise, strlen() will solve your problem.
char ch;
int len;
while( (ch=getche() ) != '13' )
{
len++;
}
or use strlen after converting from char to string by %s