This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 3 years ago.
What I'm doing wrong here in this code?
Take input as a one string.than Print the length of each word.
for example, the length of i is 1 and length of Love is 4 so print the length after the each word.
include
include
int main()
{
int i,n,count=0;
char str[20];
gets(str);
n=strlen(str);
for(i=0;i<n;i++){
if(str[i]==" "){
printf("%d",count);
count=0;
}else{
printf("%c",str[i]);
count++;
}
}
return 0;
}
The line if(str[i]==" "){ is wrong.
" " is a string and it consists of two bytes: the space character and a terminating NUL character.
You should use if(str[i]==' '){ instead.
' ' is a character and you should compare it with str[i], which is also a character.
Also, it seems you forgot to print a space character after the numbers.
One more point is that you should print the length of the last word
even if there isn't a space character after the last word.
By the way, you shouldn't use gets(),
which has unavoidable risk of buffer overrun, deprecated in C99 and deleted from C11.
You should use fgets(), which takes buffer size, instead.
fgets() saves newline characters read to the buffer while gets() doesn't,
so you should remove the newline characters if you don't want them.
An example of corrected code:
#include <stdio.h>
#include<string.h>
int main()
{
int i,n,count=0;
char str[20 + 1]; // allocate one more character for a newline character
char* lf; // for searching for a newline character
fgets(str, sizeof(str), stdin); // use fgets() instead if gets()
if ((lf = strchr(str, '\n')) != NULL) *lf = '\0'; // remove a newline character if one exists
n=strlen(str);
for(i=0;i<=n;i++){ // change < to <= for processing the terminating NUL character
if(str[i]==' ' || str[i]=='\0'){ // compare with a character, not a string
if (count>0) printf("%d",count); // avoid duplicate printing for duplicate space characters
if(i+1<n) printf(" "); // print a space if the string continues
count=0;
}else{
printf("%c",str[i]);
count++;
}
}
return 0;
}
A few issues in the code:
Comparing a character with a string literal.
No space after printing a particular word and its length.
For the last word, the comparison has to be with a null-terminator.
Not taking the null-terminator into account in the condition check of the for loop.
Making these changes, you will get the required output.
Demo here.
Note: gets is deprecated and considered dangerous to use. Use fgets instead.
Related
String.trim() in java removes all characters whose ascii value is less than or equal to 20 (space).
Any idea why Java did that instead of removing only space (ascii char 20)
public String trim() {
int len = count;
int st = 0;
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[off + st] <= ' ')) {
st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}
Because there are many different ways of having empty space, besides that " " space character. Quoting the javadoc:
Returns a copy of the string, with leading and trailing whitespace omitted.
The javadoc is clear here: it is not about space but white space. Things that would show up as "empty" - but that are in fact different from plain " " empty strings.
In other words: this is a convenience method. Such methods are designed to provide that functionality that users do need/expect.
It would be absolutely counter-intuition to provide a trim() method that only works spaces.
A very typical scenario is: you receive some string. It could be entered by a user, it could be read from a file and represent a whole line. You are not interested in any trailing tabs, spaces, new line characters. Thus the fathers of the Java language give you a method to get rid of all these different characters easily. Instead of you calling trimSpaces(), trimTabs(), trimNewLines(), etc. pp.
The ASCII character code for space is actually 32, not 20. But if you look at the sorts of characters which come before 32 you will find many types of whitespace, such as tab and carriage return. The asssumption is the average user would want to strip all such whitespace surrounding a string.
To round out the answer given by #GhostCat here is a one-liner you can use to selectively trim only space:
String input = " Hello World! ";
input = input.replaceAll("[ ]*(.*)[ ]*", "$1");
The below one-liner works. The one given by #Tim Biegeleisen doesn't remove a trailing space.
String input = " Hello World! ";
input = input.replaceFirst("^\\s++", "").replaceFirst("\\s++$","");
I'm writing a character occurrence counter in a txt file. I keep getting a result of 0 for my count when I run this:
public double charPercent(String letter) {
Scanner inputFile = new Scanner(theText);
int charInText = 0;
int count = 0;
// counts all of the user identified character
while(inputFile.hasNext()) {
if (inputFile.next() == letter) {
count += count;
}
}
return count;
}
Anyone see where I am going wrong?
This is because Scanner.next() will be returning entire words rather than characters. This means that the string from will rarely be the same as the single letter parameter(except for cases where the word is a single letter such as 'I' or 'A'). I also don't see the need for this line:
int charInText = 0;
as the variable is not being used.
Instead you could try something like this:
public double charPercent(String letter) {
Scanner inputFile = new Scanner(theText);
int totalCount = 0;
while(inputFile.hasNext()) {
//Difference of the word with and without the given letter
int occurencesInWord = inputFile.next().length() - inputFile.next().replace(letter, "").length();
totalCount += occurencesInWord;
}
return totalCount;
}
By using the difference between the length of the word at inputFile.next() with and without the letter, you will know the number of times the letter occurs in that specific word. This is added to the total count and repeated for all words in the txt.
use inputFile.next().equals(letter) instead of inputFile.next() == letter1.
Because == checks for the references. You should check the contents of the String object. So use equals() of String
And as said in comments change count += count to count +=1 or count++.
Read here for more explanation.
Do you mean to compare the entire next word to your desired letter?
inputFile.next() will return the next String, delimited by whitespace (tab, enter, spacebar). Unless your file only contains singular letters all separated by spaces, your code won't be able to find all the occurrences of letters in those words.
You might want to try calling inputFile.next() to get the next String, and then breaking that String down into a charArray. From there, you can iterate through the charArray (think for loops) to find the desired character. As a commenter mentioned, you don't want to use == to compare two Strings, but you can use it to compare two characters. If the character from the charArray of your String matches your desired character, then try count++ to increment your counter by 1.
I printed 2 strings and they are literally identical, no whitespaces cause i replaced them.
https://ideone.com/cw07LG
Here it is compiled
public class Palindrome{
public static boolean isPalindrome(String word){
int length;
String oppositeWord ="";
word = word.replace(" ","");
word = word.toLowerCase();
length = word.length();
for(int i=length-1;i>=0;i--){
if(Character.isLetter(word.charAt(i))){
oppositeWord +=word.charAt(i);
}else{
word = word.replace(word.charAt(i),'\0');
}
}
System.out.println(oppositeWord);
System.out.println(word);
return oppositeWord.equals(word);
}
public static void main(String[]args){
System.out.println(isPalindrome("Madam, I'm Adam"));
}
}
First, Java Strings are immutable and should not be manipulated character by character (that is why the Java Library has the StringBuilder and StringBuffer classes).
Second, Java Strings are not really equivalent to char[] in C/C++. They are more like char* in that they point to some other memory that holds the actual information. Changing the non-alphabetic characters to '\0' null characters is not deleting them from the string. They are not printed on the screen, but still exist in memory. (That is one way Java Strings are different from C/C++ strings ... Java Strings are not null terminated arrays of characters!)
If you add some print statements to print the length, you will find that the oppositeWord is two characters smaller than word.
System.out.println(oppositeWord.length()); // prints 11
System.out.println(word.length()); // prints 13
To really make the two Strings equal, the same characters replaced in word must also be inserted in oppositeWord at the same indices or removed altogether from both. i.e.
for(int i=length-1;i>=0;i--) {
if(Character.isLetter(word.charAt(i))) {
oppositeWord +=word.charAt(i);
} else {
word = word.replace(word.charAt(i),'\0');
oppositeWord += word.charAt(i); // << This line!
}
}
Now, both Strings will contain the same information and oppositeWord.equals(word) will hold.
Also FYI, StringBuilder and StringBuffer both have reverse() methods that could be used to simplify this process.
Replacing a character with '\0' is not the same thing as removing the character all together. It won't show up when you print it, so they will look the same, but it's still there and will make them not equal.
Try printing the lengths along with the words.
This line is wrong:
word = word.replace(word.charAt(i),'\0');
Replacing a character by \0 isn't the same as removing it. You want something like this:
word = word.replace(""+word.charAt(i), "");
However, like this comment says, there are better ways to check if a word is a palindrome.
Also, I'm not sure why, but your ideone.com shows a different output from my IDE (NetBeans). Yours shows:
madamimadam
madamimadam
false
But as Qbrute points out, the output is:
madamimadam
madam i madam
false
Which explains why the result is false. My best guess is that your on-line IDE has some trouble converting the \0 you added into text and just doesn't print anything.
It is true as mentioned by bluemoon93 that the two strings are actually not equal. The original string is madam i madam. This means it consists of spaces that makes the two strings different. I would suggest that you remove punctuation, spaces from the original string using regex. This will remove any extra spaces or punctuation.
public boolean isPalindrome(String word){
int length;
String oppositeWord ="";
word = word.toLowerCase();
length = word.length();
String newword = word.replaceAll("[\\s\\p{Punct}]", "");
for(int i=length-1;i>=0;i--){
if(Character.isLetter(word.charAt(i))){
oppositeWord +=word.charAt(i);
}
}
System.out.println(oppositeWord);
System.out.println(newword);
return oppositeWord.equals(newword);
}
The return result will now return true, since both strings are equal as they are matched by valid character and do not contain space or punctuation.
I have a variable string that might contain any unicode character. One of these unicode characters is the han 𩸽.
The thing is that this "han" character has "𩸽".length() == 2 but is written in the string as a single character.
Considering the code below, how would I iterate over all characters and compare each one while considering the fact it might contain one character with length greater than 1?
for ( int i = 0; i < string.length(); i++ ) {
char character = string.charAt( i );
if ( character == '𩸽' ) {
// Fail, it interprets as 2 chars =/
}
}
EDIT:
This question is not a duplicate. This asks how to iterate for each character of a String while considering characters that contains .length() > 1 (character not as a char type but as the representation of a written symbol). This question does not require previous knowledge of how to iterate over unicode code points of a Java String, although an answer mentioning that may also be correct.
int hanCodePoint = "𩸽".codePointAt(0);
for (int i = 0; i < string.length();) {
int currentCodePoint = string.codePointAt(i);
if (currentCodePoint == hanCodePoint) {
// do something here.
}
i += Character.charCount(currentCodePoint);
}
The String.charAt and String.length methods treat a String as a sequence of UTF-16 code units. You want to treat the string as Unicode code-points.
Look at the "code point" methods in the String API:
codePointAt(int index) returns the (32 bit) code point at a given code-unit index
offsetByCodePoints(int index, int codePointOffset) returns the code-unit index corresponding to codePointOffset code-points from the code-unit at index.
codePointCount(int beginIndex, int endIndex) counts the code-points between two code-unit indexes.
Indexing the string by code point index is a bit tricky, especially if the string is long and you want to do it efficiently. However, it is a do-able, albeit that the code is rather cumbersome.
#sstan's answer is one solution.
This will be simpler if you treat both the string and the data you're searching for as Strings. If you just need to test for the presence of that character:
if (string.contains("𩸽") {
// do something here.
}
If you specifically need the index where that character appears:
int i = string.indexOf("𩸽");
if (i >= 0) {
// do something with i here.
}
And if you really need to iterate through every code point, see How can I iterate through the unicode codepoints of a Java String? .
An ASCII character takes half the amount a Unicode char does, so it's logical that the han character is of length 2. It not an ASCII char, nor a Unicode letter. If it were the second case, the letter would be displayed correctly.
for a college project, I am doing a spelling test for children and i need to give 1 mark for a minor spelling error. For this I am going to do if the spelling has 2 characters wrong. How can I compare the saved word to the inputed word?
char wLetter1 = word1.charAt(0);
char iLetter1 = input1.charAt(0);
char wLetter2 = word1.charAt(1);
char iLetter2 = input1.charAt(1);
I have started out with this where word1 is the saved word and input1 is the user input word.
However, if I add lots of these, if the word is 3 characters long but I am trying to compare the 4th character, I will get an error? Is there a way of knowing how many characters are in the string and only finding the characters of those letters?
Just use a for loop. Since I'm assuming this is about JavaScript, calling charAt() with an index out-of-bounds will just return the empty string "".
To avoid a out-of-bounds exception you'll have to iterate up until the lower of the lengths:
int errs = Math.abs(word1.length - input1.length);
int len = Math.min(word1.length, input1.length);
for (int i = 0; i < len; i++) {
if (word1.charAt(i) != input1.charAt(i)) errs++;
}
// errs now holds the number of character mismatches