Print last character from word from char array - c

I'v got this:
char file_name[50];
strncpy(file_name, dp2->d_name, sizeof(file_name2));
// put some words in it, for example "E348C", "E348", "E348A"......
And I need to find last character from each word and check it later if it is number or letter..... but the words as you can see have not the same length....
I have no idea how to get last character...
Also char the variable file_name[50]; could be defined as char * file_name; I don't care....
Any ideas ?

Edit: It seems that the question has already been solved in the comments above, but maybe somebody comes along with a similar question in the future...
Please look at the comments.
#include <stdio.h>
#include <string.h>
int main(void) {
char file_name[50];
char inp[] = "something3";
strncpy(file_name, inp, sizeof(inp));
printf("%s\n", file_name);
// strlen returns the length of a string.
char end_char = file_name[strlen(file_name)-1];
printf("%c\n", end_char);
if (isdigit(end_char)) { // checks if end_char is a number
printf("last character is a number\n");
}
if (isalpha(end_char)){ // checks if end_char is a letter
printf("last character is a character\n");
}
return 0;
}
Sample output for inp[] = "something3":
something3
3
last character is a number
Sample output for inp[] = "somethingX":
somethingX
X
last character is a character

Related

reversing a string in c without library function

In this program I am trying to take a string as input from the user guessing that the maximum length of the string here is 40 (obviously can exceed).
I'm finding out the length and using the length to create another character array dynamically( only to prevent assigning this array with any random value) and finally, adding the characters from the last to get the reversed string.
It compiles just fine, but upon running, provides no output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[40];
char *rev;
int i=0;
int l=0;
printf("Enter any statement \n");
scanf("%[^\n]", word);
while(word[i]!='\0')
{
i++;
}
// i contains the length of the string
rev=(char *)malloc(i*sizeof(char));
while(i>0)
{
rev[l]=word[i];
i--;
l++;
}
printf("\n %s", rev);
return 0;
}
You have two (at least) problems: The first one is that you swap characters twice. The second problem is that you also include the terminator character in your swapping.
I believe you have a 'one-off' type error and are not seeing any output because the teminating \0 character is being copied to the first position of rev.
rev[l]=word[i]; should rev[l]=word[i-1];
Point 1:-
In C a string is always ended with '\0'(NULL Termination),you should always manually insert a '\0' at the end,which i think you forgot.But no worries even i did not remember it as well when i started...:) ,Experiences like these will make you from next time.
Point 2:-
Assume you have a string char str[]="ABCD" ;,In memory this would look like this
------------IN Memory----------------
| 'A' || 'B' || 'C' | | 'D' | | '\0' |
-------------------------------------
0 1 2 3 4
Just by looking we can say that its length would be 4 (we know that we don't include '\0' when calculating length). For copying in reverse we need to start with character 'D' whose index is 3,that means you have to start copying from 2nd last character whose index can be can be found from length of string -1.The mistake you did in your above program is you have used length of string (which is 4), to start copying.which copies '\0' as first character in rev[] ,Hence it provides no output.
Other points:-
Based on the above two points i have corrected the mistakes, see comments in the below program to understand it well.And i have used int j;instead of int l; because i felt so confusing.
and please use width specifier when reading strings using scanf(); In your while loop,you should change the condition from i>0 to i>=0 because when i reaches 0,i>0 condition will break the loop before copying the first character from word[] to rev[].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[40];
char *rev;
int i=0;
int j=0;
printf("Enter any statement \n");
scanf("%39[^\n]", word);//using width specifier,(POINT 1)here 39 because sizeof(word)-1, one left to accommodate '\0' at end.
while(word[i]!='\0')//calculating length of string
{
i++;
}
rev=(char *)malloc(i*sizeof(char)+1);// (POINT 1),here making +1 to accommodate '\0' at end.
i=i-1;//(POINT 2)- Last index of the array is always length of string - 1
while(i>=0)//This should be i>=0 because you also want to copy first character of input string.
{
rev[j]=word[i];
i--;
j++;
}
rev[j]='\0';//(POINT 1) You should end with '\0'.
printf("\n %s", rev);
return 0;
}
Your scanf format string looks weird. Perhaps you are using some strange feature of it that I'm unaware of, so I'll pass on that. But you need to make sure that word is a null terminated string after the user input is done.
while(word[i]!='\0')
This loops counts until it finds the null term. So i will contain the string length: you just invented the strlen() function. It will not contain the string length plus the null terminator length (1).
Therefore
rev=(char *)malloc(i*sizeof(char));
is incorrect, you need to allocate i+1 bytes.
Also, you shouldn't cast the result of malloc, because doing so is completely pointless.
And when you copy, you have to ensure that you also copy the null terminator.
Below code with just one modification should return just correct answer. I changed in 2nd while loop from:
rev[l]=word[i];
to
rev[l]=word[i-1];
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[40];
char *rev;
int i=0;
int l=0;
printf("Enter any statement \n");
scanf("%[^\n]", word);
while(word[i]!='\0')
{
i++;
}
// i contains the length of the string
rev=(char *)malloc(i*sizeof(char));
while(i>0)
{
rev[l]=word[i-1];
i--;
l++;
}
printf("\n %s", rev);
return 0;
}
The code has several memory mistakes and using static memory is also an issue. But for if you are using for practice purpose below are the changes and its explanation.
i--; // you can't place a '\0' to your rev[0] else it would always be NULL string when you print
while(i>=0)
{
rev[l]=word[i];
i--;
l++;
}
rev[l]='\0'; // string should be terminated by '\0'
printf("\n%s\n", rev);
//Reverse of a string without using string functions
#include<stdio.h>
#include<conio.h>
void main()
{
char a[40];
int j=0,len=0;
clrscr();
printf("please enter your name\n");
gets(a); // takes white spaces as characters
printf("the reverse of your name is\n");
while (a[j]!=NULL) // finding the length of the string array
{
len++;
j++;
}
for(int k=len;k>=0;k--)
{
printf("%c",a[k]);
}
getch();
}
Output - please enter your name
dwayne rock johnson
the reverse of your name is
nosnhoj kcor enyawd
As noted, array indices begin at zero and end at length-1. Moreover, if you like, you could rewrite your code in a more cryptic fashion:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[40];
char *rev;
int i=0;
int l=0;
printf("Enter any statement \n");
scanf("%[^\n]", word);
while(word[++i]);
// i contains the length of the string
rev=(char *)malloc(i*sizeof(char));
while(rev[l++]=word[i---1], i>0);
printf("%s\n", rev);
return 0;
}

Better understanding of strstr in C

I already asked on question earlier about the string function strstr, and it just turned out that I had made a stupid mistake. Now again i'm getting unexpected results and can't understand why this is. The code i've written is just a simple test code so that I can understand it better, which takes a text file with a list of 11 words and i'm trying to find where the first word is found within the rest of the words. All i've done is move the text document words into a 2D array of strings, and picked a few out that I know should return a correct value but are instead returning NULL. The first use of strstr returns the correct value but the last 3, which I know include the word chant inside of them, return NULL. If again this is just a stupid mistake I have made I apologize, but any help here on understanding this string function would be great.
The text file goes is formatted like this:
chant
enchant
enchanted
hello
enchanter
enchanting
house
enchantment
enchantress
truck
enchants
And the Code i've written is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE* file1;
char **array;
int i;
char string[12];
char *ptr;
array=(char **)malloc(11*sizeof(char*));
for (i=0;i<11;i++) {
array[i]=(char *)malloc(12*sizeof(char));
}
file1=fopen(argv[1],"r");
for (i=0;i<11;i++) {
fgets(string,12,file1);
strcpy(array[i],string);
}
ptr=strstr(array[1],array[0]);
printf("\nThe two strings chant and %s yield %s",array[1],ptr);
ptr=strstr(array[2],array[0]);
printf("\nThe two strings chant and %s yield %s",array[2],ptr);
ptr=strstr(array[4],array[0]);
printf("\nThe two strings chant and %s yield %s",array[4],ptr);
ptr=strstr(array[5],array[0]);
printf("\nThe two strings chant and %s yields %s",array[5],ptr);
return 0;
}
Get rid of the trailing \n after fgets().
for (i=0;i<11;i++) {
fgets(string, sizeof string, file1);
size_t len = strlen(string);
if (len > 0 && string[len-1] == '\n') string[--len] = '\0';
strcpy(array[i], string);
}
char *chomp(char *str){
char *p = strchr(str, '\n');
if(p)
*p = '\0';
return str;
}
...
strcpy(array[i], chomp(string));

Using Pointers and strtok()

I'm building a linked list and need your assistance please as I'm new to C.
I need to input a string that looks like this: (word)_#_(year)_#_(DEFINITION(UPPER CASE))
Ex: Enter a string
Input: invest_#_1945_#_TRADE
Basically I'm looking to build a function that scans the DEFINITION and give's me back the word it relates to.
Enter a word to search in the dictionary
Input: TRADE
Output: Found "TREADE" in the word "invest"
So far I managed to come up using the strtok() function but right now I'm not sure what to do about printing the first word then.
Here's what I could come up with:
char split(char words[99],char *p)
{
p=strtok(words, "_#_");
while (p!=NULL)
{
printf("%s\n",p);
p = strtok(NULL, "_#_");
}
return 0;
}
int main()
{
char hello[99];
char *s = NULL;
printf("Enter a string you want to split\n");
scanf("%s", hello);
split(hello,s);
return 0;
}
Any ideas on what should I do?
I reckon that your problem is how to extract the three bits of information from your formatted string.
The function strtok does not work as you think it does: The second argument is not a literal delimiting string, but a string that serves as a set of characters that are delimiters.
In your case, sscanf seems to be the better choice:
#include <stdlib.h>
#include <stdio.h>
int main()
{
const char *line = "invest_#_1945 _#_TRADE ";
char word[40];
int year;
char def[40];
int n;
n = sscanf(line, "%40[^_]_#_%d_#_%40s", word, &year, def);
if (n == 3) {
printf("word: %s\n", word);
printf("year: %d\n", year);
printf("def'n: %s\n", def);
} else {
printf("Unrecognized line.\n");
}
return 0;
}
The function sscanf examines a given string according to a given pattern. Roughly, that pattern consists of format specifiers that begin with a percent sign, of spaces which denote any amount of white-space characters (including none) and of other characters that have to be matched varbatim. The format specifiers yield a result, which has to be stored. Therefore, for each specifier, a result variable must be given after the format string.
In this case, there are several chunks:
%40[^_] reads up to 40 characters that are not the underscore into a char array. This is a special case of reading a string. Strings in sscanf are really words and may not contain white space. The underscore, however, would be part of a string, so in order not to eat up the underscore of the first delimiter, you have to use the notation [^(chars)], which means: Any sequence of chars that do not contain the given chars. (The caret does the negation here, [(chars)] would mean any sequence of the given chars.)
_#_ matches the first delimiter literally, i.e. only if the next chars are underscore hash mark, underscore.
%d reads a decimal number into an integer. Note that the adress of the integer has to be given here with &.
_#_ matches the second delimiter.
%40s reads a string of up to 40 non-whitespace characters into a char array.
The function returns the number of matched results, which should be three if the line is valid. The function sscanf can be cumbersome, but is probably your best bet here for quick and dirty input.
#include <stdio.h>
#include <string.h>
char *strtokByWord_r(char *str, const char *word, char **store){
char *p, *ret;
if(str != NULL){
*store = str;
}
if(*store == NULL) return NULL;
p = strstr(ret=*store, word);
if(p){
*p='\0';
*store = p + strlen(word);
} else {
*store = NULL;
}
return ret;
}
char *strtokByWord(char *str, const char *word){
static char *store = NULL;
return strtokByWord_r(str, word, &store);
}
int main(){
char input[]="invest_#_1945_#_TRADE";
char *array[3];
char *p;
int i, size = sizeof(array)/sizeof(char*);
for(i=0, p=input;i<size;++i){
if(NULL!=(p=strtokByWord(p, "_#_"))){
array[i]=p;//strdup(p);
p=NULL;
} else {
array[i]=NULL;
break;
}
}
for(i = 0;i<size;++i)
printf("array[%d]=\"%s\"\n", i, array[i]);
/* result
array[0]="invest"
array[1]="1945"
array[2]="TRADE"
*/
return 0;
}

How to extract a substring from a string in C?

I tried using strncmp but it only works if I give it a specific number of bytes I want to extract.
char line[256] = This "is" an example. //I want to extract "is"
char line[256] = This is "also" an example. // I want to extract "also"
char line[256] = This is the final "example". // I want to extract "example"
char substring[256]
How would I extract all the elements in between the ""? and put it in the variable substring?
Note: I edited this answer after I realized that as written the code would cause a problem as strtok doesn't like to operate on const char* variables. This was more an artifact of how I wrote the example than a problem with the underlying principle - but apparently it deserved a double downvote. So I fixed it.
The following works (tested on Mac OS 10.7 using gcc):
#include <stdio.h>
#include <string.h>
int main(void) {
const char* lineConst = "This \"is\" an example"; // the "input string"
char line[256]; // where we will put a copy of the input
char *subString; // the "result"
strcpy(line, lineConst);
subString = strtok(line,"\""); // find the first double quote
subString=strtok(NULL,"\""); // find the second double quote
printf("the thing in between quotes is '%s'\n", subString);
}
Here is how it works: strtok looks for "delimiters" (second argument) - in this case, the first ". Internally, it knows "how far it got", and if you call it again with NULL as the first argument (instead of a char*), it will start again from there. Thus, on the second call it returns "exactly the string between the first and second double quote". Which is what you wanted.
Warning: strtok typically replaces delimiters with '\0' as it "eats" the input. You must therefore count on your input string getting modified by this approach. If that is not acceptable you have to make a local copy first. In essence I do that in the above when I copy the string constant to a variable. It would be cleaner to do this with a call to line=malloc(strlen(lineConst)+1); and a free(line); afterwards - but if you intend to wrap this inside a function you have to consider that the return value has to remain valid after the function returns... Because strtok returns a pointer to the right place inside the string, it doesn't make a copy of the token. Passing a pointer to the space where you want the result to end up, and creating that space inside the function (with the correct size), then copying the result into it, would be the right thing to do. All this is quite subtle. Let me know if this is not clear!
if you want to do it with no library support...
void extract_between_quotes(char* s, char* dest)
{
int in_quotes = 0;
*dest = 0;
while(*s != 0)
{
if(in_quotes)
{
if(*s == '"') return;
dest[0]=*s;
dest[1]=0;
dest++;
}
else if(*s == '"') in_quotes=1;
s++;
}
}
then call it
extract_between_quotes(line, substring);
#include <string.h>
...
substring[0] = '\0';
const char *start = strchr(line, '"') + 1;
strncat(substring, start, strcspn(start, "\""));
Bounds and error checking omitted. Avoid strtok because it has side effects.
Here is a long way to do this: Assuming string to be extracted will be in quotation marks
(Fixed for error check suggested by kieth in comments below)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char input[100];
char extract[100];
int i=0,j=0,k=0,endFlag=0;
printf("Input string: ");
fgets(input,sizeof(input),stdin);
input[strlen(input)-1] = '\0';
for(i=0;i<strlen(input);i++){
if(input[i] == '"'){
j =i+1;
while(input[j]!='"'){
if(input[j] == '\0'){
endFlag++;
break;
}
extract[k] = input[j];
k++;
j++;
}
}
}
extract[k] = '\0';
if(endFlag==1){
printf("1.Your code only had one quotation mark.\n");
printf("2.So the code extracted everything after that quotation mark\n");
printf("3.To make sure buffer overflow doesn't happen in this case:\n");
printf("4.Modify the extract buffer size to be the same as input buffer size\n");
printf("\nextracted string: %s\n",extract);
}else{
printf("Extract = %s\n",extract);
}
return 0;
}
Output(1):
$ ./test
Input string: extract "this" from this string
Extract = this
Output(2):
$ ./test
Input string: Another example to extract "this gibberish" from this string
Extract = this gibberish
Output(3):(Error check suggested by Kieth)
$ ./test
Input string: are you "happy now Kieth ?
1.Your code only had one quotation mark.
2.So the code extracted everything after that quotation mark
3.To make sure buffer overflow doesn't happen in this case:
4.Modify the extract buffer size to be the same as input buffer size
extracted string: happy now Kieth ?
--------------------------------------------------------------------------------------------------------------------------------
Although not asked for it -- The following code extracts multiple words from input string as long as they are in quotation marks:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char input[100];
char extract[50];
int i=0,j=0,k=0,endFlag=0;
printf("Input string: ");
fgets(input,sizeof(input),stdin);
input[strlen(input)-1] = '\0';
for(i=0;i<strlen(input);i++){
if(input[i] == '"'){
if(endFlag==0){
j =i+1;
while(input[j]!='"'){
extract[k] = input[j];
k++;
j++;
}
endFlag = 1;
}else{
endFlag =0;
}
//break;
}
}
extract[k] = '\0';
printf("Extract = %s\n",extract);
return 0;
}
Output:
$ ./test
Input string: extract "multiple" words "from" this "string"
Extract = multiplefromstring
Have you tried looking at the strchr function? You should be able to call that function twice to get pointers to the first and second instances of the " character and use a combination of memcpy and pointer arithmetic to get what you want.

Strings in C Language

How can you code this in C language if the output is like this? I need strings format of the code because our topic is strings.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char my_string[50];
printf("Enter a word:");
scanf("%s", my_string);
printf("Enter a word:");
scanf("%s", my_string);
// Some unknown code here...
// this part is my only problem to solve this.
getch();
}
Output:
Hello -> (user input)
World -> (user input)
HWeolrllod -> (result)
Okay, you need to do some investigating. We don't, as a general rule, do people's homework for them since:
it's cheating.
you'll probably get caught out if you copy verbatim.
it won't help you in the long run at all.
The C library call for user input that you should use is fgets, along the line of:
char buffer[100];
fgets (buffer, sizeof(buffer), stdin);
This will input a string into the character array called buffer.
If you do that with two different buffers, you'll have the strings in memory.
Then you need to create pointers to them and walk through the two strings outputting alternating characters. Pointers are not an easy subject but the following pseudo-code may help:
set p1 to address of first character in string s1
set p1 to address of first character in string s1
while contents of p1 are not end of string marker:
output contents of p1
add 1 to p1 (move to next character)
if contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
while contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
Translating that into C will take some work but the algorithm is solid. You just need to be aware that a character pointer can be defined with char *p1;, getting the contents of it is done with *p1 and advancing it is p = p + 1; or p1++;.
Short of writing the code for you (which I'm not going to do), there's probably not much else you need.
void main()
{
char my_string1[50],my_string2[50]; int ptr;
ptr=0;
printf("Enter a word : ");
scanf("%s",my_string1);
printf("enter a word");
scanf("%s",my_string2);
while(my_string1[ptr]!='\0' && my_string2[ptr]!='\0')
{
printf("%c%c",my_string1[ptr],my_string2[ptr]);
ptr++;
}
if(my_string1[ptr]!='\0')
{
while(my_string1[ptr]!='\0')
{ printf("%c",my_string1[ptr]);
ptr++;
}
}
else
{
while(my_string2[ptr]!='\0')
{printf("%c",my_string2[ptr]);
ptr++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char my_string1[50],my_string2[50];
int i,l1=1,l2=0;
printf("Enter a word:");
scanf("%s", my_string1);
printf("Enter a word:");
scanf("%s", my_string2);
l1=strlen(my_string1); /* Length of 1st string */
l2=strlen(my_string2); /* Length of 2nd string */
if(l1==l2)
{
for(i=0;i<l1;i++)
{
printf("%c%c",my_string1[i],my_string2[i]);
}
}
else
{
printf("Length of the entered strings do not match");
}
}
This is your required code.
You can see that output needs to be a String containing all chars of User String1 and User String2 one by one...
You can do this like...
//add #include<String.h>
int l1=strlen(s1);
int l2=strlen(s2);
if(l1!=l2)
{
printf("length do not match");
return 0;
}
char ansstr[l1+l2];
int i,j=0,k=0;
for(i=0;i<l1+l2;i=i+2)
{
ansstr[i]=s1[j];
ansstr[i+1]=s2[k];
j++;
k++;``
}
//ansstr is your answer
Ok, here's your code. Come on guys, if he asked here it means he can't solve this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char str1[] = "abcdefghijklmopq";
char str2[] = "jklm";
int len1 = strlen(str1);
int len2 = strlen(str2);
int c1 = 0, c2 = 0;
int max = (len1 > len2) ? len1 : len2 ;
char *result = malloc(len1 + len2);
for(c1 = 0; c1 <= max; c1++) {
if(c1 < len1)
result[c2++] = str1[c1];
if(c1 < len2)
result[c2++] = str2[c1];
}
result[c2] = 0;
printf("\n%s\n", result);
return 0;
}
Basically the loop picks up a character from str1 and appends it to result. Then it picks a character, which stands in the same position as the first from str2 and appends it to result, just as before. I increment c2 by 2 every time because I'm adding 2 chars to result. I check if c1 is bigger that the length of the strings because I want to copy only the characters in the string without the terminating \0. If you know that your strings have the same length you can omit these ifs.

Resources