put a mask on a C string - c

I have a C string which has a value x.x.x where x can be 1 to 9. what's a good algorithm to make it x.x.8 for example the last digit fixed at 8.
I am thinking of using strtok function.

use this function:
void mask_string(char s[]) {
int j = 0,i;
while (s[j] != '\0')
j++;
i = j-1;
s[i] = '8';
}
this works even if you don't have a fixed length string

Related

C programming by K&R what does the last k>0 do in the strindex function?

From ANSI C programming by K&R (page69), there is a strindex function, which will return a position of the fisrt search-for string in the source string:
#include <stdio.h>
#define MAXLINE 1000 //max input length
int getline(char line[], int max);
int Strindex(char source[], char searchfor[]);
char pattern[] = "ould";
int main()
{
char line[MAXLINE];
int found = 0;
while (getline(line, MAXLINE) > 0)
if (Strindex(line, pattern) >= 0) {
printf("%s", line);
found++;
}
return found;
} // end of main function
int getline(char s[], int lim)
{
int c, i;
i = 0;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
int Strindex(char s[], char t[])
{
int i, j, k;
for (i = 0; s[i] != '\0'; i++) {
for (j = i, k = 0; s[j] == t[k]; j++, k++)
;
if (k > 0 && t[k] == '\0') //here is the k
return i;
}
return -1;
}
My question is:
when j = i, k = 0; s[j] != t[k] (if the t[] and s[] are not empty strings), It seems t[0] will never get a value of \0? Then, what does this k>0 do in the last if statement?: if (k > 0 && t[k] == '\0')
If I get it right the Strindex() function checks if the string t is inside the string s.
So the if (k > 0 && t[k] == '\0') statement means that every character so far of the string t is the same with the string s and we reached the end of string t, so we got it mached and it returns the index of string s where the string t begins.
Well simply it is discarding all the 0 length targets. This is needed if you want to discard 0 length targets.(For this code. But there are better ways to do that).
Suppose s is "CODE" and t is an empty string containing \0. So in this case it enters for loop and the inner for loop breaks. And then k=0 and if that condition (k>0) is omitted if( t[k]=='\0') is used then it will be true and it is returned. But again one may argue that it should match any indices if empty target is passed.
Otherwise if t is empty then this function will return 0 as a string index. It seems to be a waste to put this condition into cycle though.
seems as it's not needed, but before touching any code from K&R, please, do full thoroughly checking.... probably it's needed. :) (edit:) indeed, that checks the case of calling strindex(3) with a null string "" second parameter to fail, instead of succeeding at the first case.
the next code always succeeds at index 0 if you call:
strindex("something", "");
without that test.
Indeed, i maintains the source string index, j is the index of the being checked char, and k is the index in the second string of the checked char (the matched length). the k > 0 test makes it fail in case the second string index is 0 as then, the null string has been tried, and it always succeeds at length 0.
The check of null string second parameter is more general, and as you can get that second string from the result of another calculation, it seems better to consider that case than to disallow it.

Searching through pointer array to count letter uses

Ok, so I am not looking for an a full answer please. I just don't know where to begin with this. I have a code that is declaring a pointer array full of names. The goal is to write a code to search the names and count each letter that is used.
/*
* Search through each character in s,
* which is array containing n strings,
* and update the global count array
* with the correct character counts.
* Note: check the examples to see
* if the counts should be case
* sensitive or case insensitive.
*/
void letterCount(char * s[], int n){
//Implement this function
int c = 0,x; // This is what I've done and I
char p = 'a', j = 'z'; // don't know where im messing up.
while (s[c] != '\0') { // I know I can't compare pointer
if (s[c] >= p && s[c] <= j ){ // and integer.
x = *s[c] - 'a';
count[x]++;
}
c++;
}
}
/*
* Initialize each value in the global
* count array to zero.
*/
void initializeCount(){
//Implement this function
int i;
for (i = 0; i < 26; i++){ // Also not sure if this is correct.
count[i] = 0;
}
}
The output should count the letter uses into an array called count[26].
Any suggestions please?
s[c] is not a character, it's a pointer, you are comparing pointer and character p which is not valid,
if (s[c] >= p && s[c] <= j ) // here you are comparing address & char, which you shouldn't
rotate one more loop for comparing each char of string.
Modify your code as
void letterCount(char * s[], int n){
//Implement this function
int c = 0,x,i; // This is what I've done and I
char p = 'a', j = 'z'; // don't know where im messing up.
// assuming n is no of string, rotate main loop from 0 to n
while (c<n) {
for(i=0;s[c][i]!='\0';i++) // I know I can't compare pointer
if (s[c][i] >= p && s[c][i] <= j ){ // and integer.
x = s[c][i] - 'a';
count[x]++;
}
c++;
}
}
I hope you got this.

Strip numbers from a string in C

I'm looking for a simple solution for stripping numbers from a string.
Example: "GA1UXT4D9EE1" => "GAUXTDEE"
The occurrence of the numbers inside the string is erratic hence I cannot rely on functions such as scanf().
I'm new at programming in C.
Thanks for any help.
I will give you some tips:
You need to creat a new string.
Iterat over the original string.
Check if the current character is between the ascii values of numbers
If not, add it to the new string.
char stringToStrip[128];
char stripped[128];
strcpy(stringToStrip,"GA1UXT4D9EE1");
const int stringLen = strlen(stringToStrip);
int j = 0;
char currentChar;
for( int i = 0; i < stringLen; ++i ) {
currentChar = stringToStrip[i];
if ((currentChar < '0') || (currentChar > '9')) {
stripped[j++] = currentChar;
}
}
stripped[j] = '\0';
iterate through the string and check for the ascii value.
for(i = 0; i < strlen(str); i++)
{
if(str[i] >= 48 && str[i] <= 57)
{
// do something
}
}
I would agree that walking through would be an easy way to do it, but there is also an easier function to do this. You can use isdigit(). C++ documentation has an awesome example. (Don't worry, this also works in c.)
http://www.cplusplus.com/reference/cctype/isdigit/
Here is the code to do it.
int i;
int strLength = strlen(OriginalString);
int resultPosCtr = 0;
char *result = malloc(sizeof(char) * strLength);//Allocates room for string.
for(i = 0; i < strLength; i++){
if(!isdigit(OriginalString[i])){
result[resultPosCtr] = OriginalString[i];
resultPosCtr++;
}
}
result[resultPosCtr++] = '\0'; //This line adds the sentinel value A.K.A the NULL Value that marks the end of a c style string.
Everyone has it right.
Create a new char[] A.K.A. C style string.
Iterate over the original string
Check to see if the character at that iteration is a number
if not add to new string

search for '\n in char pointer use c

I am trying to loop a char*str use this to find out how many lines:
char *str = "test1\ntest2\ntest3";
int lines = 0;
for(int i = 0 ; i < ?? ; i ++ )
{
if(str[i] == '\n') {
lines++;
}
}
I am not sure what to put at the ??, the question is :
1.I mean do I need to use strlen(str) + 1 ?
2.when the str is "test1\ntest2\ntest3\n",does the code still calculate correct lines?
I am using gcc by the way,thanks
every literal string ends with \0 which is a null character..It depicts the end of the string
So,
You can do this
for(int i = 0 ; str[i]!='\0' ; i ++ )
To extend the already-existent good answers: the idiomatic way for looping through a C string is
const char *s = "abc\ndef\nghi\n";
int lines = 0;
int nonempty = 0;
while (*s) {
nonempty = 1;
if (*s++ == '\n') lines++;
}
If you don't want to count the last empty line as a separate line, then add
if (nonempty && s[-1] == '\n' && lines > 0) lines--;
after the while loop.
Take the length of the string and iterate through all characters.
const unsigned long length=strlen(str);
for(int i = 0 ; i < length ; i ++ )
{
if(str[i] == '\n') {
lines++;
}
}
The following will deliver the same result regardless if the last character is a newline or not.
char *abc = "test1\ntest2\ntest3";
int lines = 0;
{
bool lastWasNewline = true;
char * p = abc;
for (; *p; ++p) {
if (lastWasNewline) ++lines;
lastWasNewline = *p == '\n';
}
}
1.I mean do I need to use strlen(str) + 1 ?
no, just use str[i] for i < ??, this tests if that is the 0 character which terminates the string
2.when the abc is "test1\ntest2\ntest3\n",does the code still calculate correct lines?
no, you code assumes that the input is broken into one input line per buffer line[j].
in place of ?? put strlen(abc) and make sure #include <string.h>
For better efficiency do
int length= strlen(abc);
and then use i < length
Or use str[i]!= '\0'

Using histogram to find the most common letter in an array

This is what I came up with, but I always get a Run-Time Check Failure #2 - Stack around the variable 'h' was corrupted.
int mostCommonLetter(char s[]) {
int i=0, h[26],k=0, max=0, number=0;
while ( k < 26){
h[k] = '0';
k++;
}
while(s[i] != '\0'){
h[whichLetter(s[i])] = h[whichLetter(s[i])]+1;
i++;
}
h[26] = '\0';
for(i=0;h[i]!='\0';i++){
if(h[i] > max)
number=i;
}
return number;
}
You cannot do h[26] = '\0'; - h has 26 elements indexed 0..25. As you know the length of h you don't need to 0-terminate it, simply do for (i=0; i < 26; ++i)
Also, are you certain whichLetter always returns a value in the 0..25 range? What does it do if it e.g. encounters a space?
This writes past the end of the array:
h[26] = '\0';
Make the for loop depend on the length rather than the last character:
for(i=0;i<26;i++){
if(h[i] > max)
number=i;
}

Resources