I have a question regarding char pointers.
I am reading a file in C, using fgets. This is a short overview so you can understand what I would like to do:
char configline[configmax_len + 1]; //configmax_len is the max value I need
while(fgets(configline, sizeof(configline), config){ //config is the file
char *configvalue = strtok(configline, " ");
if (configvalue[0] == "#"){
continue;
}
…
}
char * configvalue is a pointer to the current line being read. What I would like to check is if the first character of the line is a "#".
However when I do the if statement: if (configvalue[0] == "#"), the compiler throws an error: comparison between pointer and integer.
How could I check if the first character of the string a pointer is pointing to is a certain value?
try using
if (configvalue[0] == '#'){
this should compile nicely
Use single quotes to denote a single character; double quotes denote strings, which are represented by a pointer to the first character, hence the error message.
Strtok returns a pointer to a nul terminated string, but you're comparing this with a string constant using ==:
if (configvalue[0] == "#")
Firstly, configvalue is a pointer, so you could do something like:
if (*configvalue == '#')
To dereference the pointer and get the first character in the output string.
Related
I am writing a program in C for a basic calculator. I am trying to do this using what I have learned so far: printf() and scanf() functions. I am passing arguments into my program through the command line. I am assuming three arguments will be passed at a time which includes: first int, an operator, and the second int. I want to check if the second arg passed is an operator and then check if it's +,-,*... so on. Here is what I came up with:
int main(int argc, char **argv) {
scanf("%d %c %d", &a, &oper, &b);
if (oper != 43) {
printf("Error: Operator is not a +");
return(1);
}
}
So obviously, I have omitted a lot of the code and kept the relevant part. Here I am just checking if the oper is a +. The ASCII key is 43 so I thought this would work but no luck! Any ideas? (I would like to see if I can do this just with printf and scanf if possible)
EDIT: For example if 12 b 13 was entered, it should return the error above. Same goes for '10 +a 10' or '10 ++ 10'.
Firstly I would highly recommend looking at the man-pages for any C library function you come across, they have a lot of useful information. It seems like you are using scanf() improperly as it is not made to be used with command line arguments.
You can check for matches for a single character by comparing the argument like this:
if(argv[2][0] == '+') ...
(argv[0] is the program's file name).
If would would like to compare string you can use strcmp(). But for the operator example you can get away with just checking the first and second characters in the argument like this:
if(argv[2][0] == '+' && argv[2][0] == '\0') ...
What this does is compare the first two characters of the argument. It first checks for the '+' and then checks if that is the end of the string with by checking for the null terminator '\0'.
We can make the assumption that any argument has at least two characters, the visible character and a null terminator. Performing this on other strings has no guarantee of this however.
The other characters, specifically the numbers need to be converted from their respective ASCII values to integers. You can use atoi or strtol to do this, although atoi will most likely be easier for you.
As David C. Rankin pointed out, **argv is a double pointer which at a high level and in most cases you can treat as a double array. In C a string is actually just an array of type char, so what argv[2] is doing above is first accessing the third index of **argv, this is now de-referenced to a type char * where the string (char array) is located. This can then further be de-referenced by the [0] in argv[2][0] to look at the first char of the string.
Code example:
char **my_arrays = argv; // a array of arrays
char *array = *argv; // de-references to index 0 in argv
char *array = *(argv + 1); // de-references to index 1 in argv
char *array = argv[0]; // de-references to index 0 in argv
char *array = argv[1]; // de-references to index 1 in argv
char first_char = *(*argv) // the first char of the first array of argv
char first_char = *(argv[0]) // the same as above
char first_char = argv[0][0] // the same as above
A side note. All strings in C should end in a null terminator which can be represented by NULL, 0, or '\0' values. This will represent the end of the string and many C functions rely on this to know when to stop.
Also NULL is technically a C macro, but you don't need to treat it any differently than 0 because it literally just expands to 0.
It's char **argv. As Some programmer dude said, you should reread your book/tutorial.
scanf doesn't read arguments. It reads from stdin.
Arguments are of type char* and are stored in argv. To convert these arguments to integers, use atoi or strtol (preferably strtol). See this for more info.
If you want to read from stdin using scanf, that is fine, and what you have will work as long as you instead input the data into stdin, and not as command line arguments.
Given the following I am getting a segmentation fault and I am not sure if it is because I am testing against a pointer or other issue.
What is the correct way to test if the 4th character is a comma?
string is read from fifo abc,def,xyz
char in[BUFFER] = {'\0'};
if ((in_fl = open(*fifofile, O_RDONLY)) == -1)
{
while (read(in_fl, in, BUFFER)>0) {
doParseInput(&in);
}
void *doParseInput(char *inputread){
//copy string to use later....
char* theParsedString = calloc(strlen(inputread)+1, sizeof(char));
strcpy(theParsedString , inputread);
if (strcmp(theParsedString[3], ",") == 0){ //causes seg fault
I have also tried using the passed string directly, but also seg fault
if (strcmp(inputread[3], ",") == 0){ //causes seg fault
To pass a buffer to a function, don't use &.
Instead:
doParseInput(in);
To compare the 4th character of a buffer (index == 3):
if (theParsedString[3] == ','){
(Notice the single-quotes, meaning Character-Value, rather than the double-quotes, which would mean "String")
First, you're passing the wrong type of argument to doParseInput. It expects a char * but you're passing it a char (*)[]. Your compiler should have warned you of this.
The other issue is that you're using a string comparison to check a single character. You need to use a character constant (i.e. use single quotes not double quotes) and compare that against the array member directly.
if (theParsedString[3] == ',') {
I am learning C and a I came across this function in my study materials. The function accepts a string pointer and a character and counts the number of characters that are in the string. For example for a string this is a string and a ch = 'i' the function would return 3 for 3 occurrences of the letter i.
The part I found confusing is in the while loop. I would have expected that to read something like while(buffer[j] != '\0') where the program would cycle through each element j until it reads a null value. I don't get how the while loop works using buffer in the while loop, and how the program is incremented character by character using buffer++ until the null value is reached. I tried to use debug, but it doesn't work for some reason. Thanks in advance.
int charcount(char *buffer, char ch)
{
int ccount = 0;
while(*buffer != '\0')
{
if(*buffer == ch)
ccount++;
buffer++;
}
return ccount;
}
buffer is a pointer to a set of chars, a string, or a memory buffer holding char data.
*buffer will dereference the value at buffer, as a char. This can be compared with the null character.
When you add to buffer - you are adding to the address, not the value it points to, buffer++ adds 1 to the address, pointing to the next char. This means that now *buffer results in the next character.
In the loop you are incrementing the pointer buffer until it points to the null character, at which point you know you scanned the whole string. Instead of buffer[j], which is equivalent to *(buffer+j), we are incrementing the pointer itself.
When you say buffer++ you increment the address stored in buffer by one.
Once you internalize how pointers work, this code is cleaner than the code that uses a separate index to scan the character string.
In C and C++, arrays are stored in sequence, and an array is stored according to its first address and length.
Therefore *buffer is actually the address of the first byte, and is synonymous with buffer[0]. Because of this, you can use buffer as an array, like this:
int charcount(char *buffer, char ch)
{
int ccount = 0;
int charno = 0;
while(buffer[charno] != '\0')
{
if(buffer[charno] == ch)
ccount++;
charno++;
}
return ccount;
}
Note that this works because strings are null terminated - if you don't have a null termination in the character array pointed to by *buffer it will continue reading forever; you lose the bit where c knows how long the array is. This is why you see so many c functions to which you pass a pointer and a length - the pointer tells it the [0] position of the array, and the size you specify tells it how far to keep reading.
Hope this helps.
In my program, I am making a char line[MAXLINE] and then using it in:
fgets(line, sizeof line, f);
I can then print this line with
printf("%s\n",line);
However, trying something like
printf("%s\n",line[10]);
warns me that line[10] is of type int, and something like
printf("%s\n",line + 10);
prints from character 10 onwards.
how can I just get the nth character of this string?
You can get the nth character like so:
char ch = line[10];
But you can't print it as a string, because it's not a string. Print it as a character:
printf("%c\n", line[10]);
What you are doing when you use %s in the format string in printf is printing the null-terminated string starting from the the provided pointer.
line+10 is the pointer to the 11th character in the string so it prints everything it finds in memory until it encounters /0 (null) character.
To print a single character you have to use %c in the format string.
printf("%c",line+10);
printf("%s\n",line + 10); // %s expects a char *
Instead print like this -
printf("%c\n",line + 10);
how can I just get the nth character of this string?
With strlen() function from <string.h> you can get length of string. Thus easily you can get the nth character. of the string.
The below will also work as a string in C is a char pointer to the first character. (Strings are terminated in memory with the character \0, that's how programs know where they end.)
line is a pointer to the first character and it can be advanced to the 10th character, as below (we have to advance it by 9, as no advance points to the first character).
* dereferences the pointer to get the actual value.
#include <stdio.h>
int main()
{
char line[] = "abcdefghijkl";
printf("%c\n", *(line+9));
return 0;
}
I'm new to C and I'm having some troubles with pointers.
In one function (used to print the words) I have a parameter const char *description, which is pointing to a string or char array like "There is a faint outline of a face visible".
In another function I'm going to have a pointer which points to the first character in the description, then move along until it finds a non-space.
char *pointerToFindFirstChar(char *description){
/* Get my pointer to point to first char in description*/
while (*pointerToFindFirstChar == ' ');
pointerToFindFirstChar++;
return pointer
}
I am unsure how I can do that though.
what I'm trying to achieve is to find the first non space character in a string which is being pointed at by description and store that in another pointer.(hope that makes sense)
Try this:
char *pointerToFindFirstChar(char *description)
{
while(*description == ' ')
description++;
return description;
}
Note that checking for the null byte at the end of the string is unnecessary, as when *pointer == '\0', the condition on the while loop while be false and the loop will end anyway.
Getting rid of the ; at the end of the while line is important; otherwise, the loop will have no body and either run 0 times or infinitely (since pointer would never be changed in the loop). If it ran 0 times, then the increment would happen after exiting the loop.
char *find_first_char(char *desc)
{
while (*desc == ' ') desc++;
return desc;
}
Just for the record, it is possible to have the post-increment directly in the condition of the loop:
char *pointerToFindFirstChar(char *description)
{
while (*description++ == ' ');
return description;
}
In this case you do have an empty loop body because the increment is performed right after the evaluation of the pointer inside the loop condition.
You are currently looking for any different character in your char array. That can also be an exclamation mark or a colon.
Wouldn't it be better to use something like isalnum() or isalpha() ?
If you are looking for a Digit (0-9) or Alpha-char (a-z or A-Z) then use isalnum else use isalpha.
char * pointerToFindFirstChar(char * description)
{
while(*description && !isalnum(*description))
description++;
return description;
}
or
char * pointerToFindFirstChar(char * description)
{
while(*description && !isalpha(*description))
description++;
return description;
}
It'll add some overhead though. Also, checking for the end of the char array would be required in this case.
An other option would be is to use isspace() this will check for any white-space character.
See here for these function descriptions: http://www.java2s.com/Code/C/ctype.h/Catalogctype.h.htm