How do I convert a string to lowercase? - cs50

I don't know how to convert a word into complete lowercase in cs50. I have to convert words into lowercase to check it properly.
Below is my code so far
bool check(const char *word) {
char *lword[strlen(word)];
for (i = 0; i < strlen(word); i++) {
lword[i] = tolower(int
word[i]);
}
node *current;
int hashnum = hash(word);
if (table[hashnum] == NULL)
return false;
current = table[hashnum];
while (current->next != NULL) {
if (strcmp(current->word, word) == 0)
return true;
else
current = current->next;
}
return false;
}

This declaration char *lword[strlen(word)]; is a problem. it declares lword as an array of strings (aka char*). An array of chars would be more appropriate. (Also, program would probably complain when lword is sent as an argument to hash function.) Don't forget to declare the lower case word large enough to accommodate the null-terminator, and null-terminate it. Don't forget to send the lower-case word to hash, instead of the original word.

Related

Program to find if a string is a palindrome keeps on failing. Even after using toLowerCase() command for both strings, output doesn't come

import java.util.Scanner;
class Palindrome_string
{
public static void main()
{
System.out.println("\f");
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string");
String a = sc.nextLine();
int b = a.length();
String rev = "";
for (int i = b - 1; i >= 0; i--)
{
char c = a.charAt(i);
rev = rev + c;
}
System.out.println("Original word "+a);
System.out.println("Reversed word "+rev);
a = a.toLowerCase();
rev = rev.toLowerCase();
if (a == rev)
{
System.out.println("It is a palindrome");
}
else
{
System.out.println("It is not a palindrome");
}
sc.close();
}
}
The program compiles properly. Still, when running the program, the message which tells if it is a palindrome prints incorrectly. What changes do I make? Here is a picture of the output. Even though the word 'level' (which is a palindrome) has been inputted, it shows that it isn't a palindrome. What changes should I make? output pic
You should not use == to compare two strings because it compares the reference of the string, i.e. whether they are the same object or not.
Use .equals() instead. It tests for value equality. So in your case:
if (a.equals(rev))
{
System.out.println("It is a palindrome");
}
Also try not to use single-letter variable names except for index variables when iterating over a list etc. It's bad practice.

Append Char To StringBuilder C++/CLI

I am trying to use StringBuilder to create the output that is being sent over the serial port for a log file. The output is stored in a byte array, and I am recursing through it.
ref class UART_G {
public:
static array<System::Byte>^ message = nullptr;
static uint8_t message_length = 0;
};
static void logSend ()
{
StringBuilder^ outputsb = gcnew StringBuilder();
outputsb->Append("Sent ");
for (uint8_t i = 0; i < UART_G::message_length; i ++)
{
unsigned char mychar = UART_G::message[i];
if (
(mychar >= ' ' && mychar <= 'Z') || //Includes 0-9, A-Z.
(mychar >= '^' && mychar <= '~') || //Includes a-z.
(mychar >= 128 && mychar <= 254)) //I think these are okay.
{
outputsb->Append(L""+mychar);
}
else
{
outputsb->Append("[");
outputsb->Append(mychar);
outputsb->Append("]");
}
}
log_line(outputsb->ToString());
}
I want all plain text characters (eg A, :) to be sent as text, while functional characters (eg BEL, NEWLINE) will be sent like [7][13].
What is happening is that the StringBuilder, in all cases, is outputting the character as a number. For example, A is being sent out as 65.
For example, if I have the string 'APPLE' and a newline in my byte array, I want to see:
Sent APPLE[13]
Instead, I see:
Sent 6580807669[13]
I have tried every way imaginable to get it to display the character properly, including type-casting, concatenating it to a string, changing the variable type, etc... I would really appreciate if anyone knows how to do this. My log files are largely unreadable without this function.
You're getting the ASCII values because the compiler is choosing one of the Append overloads that takes an integer of some sort. To fix this, you could do a explicit cast to System::Char, to force the correct overload.
However, that won't necessarily give the proper results for 128-255. You could cast a value in that range from Byte to Char, and it'll give something, but not necessarily what you expect. First off, 0x80 through 0x9F are control characters, and whereever you're getting the bytes from might not intend the same representation for 0xA0 through 0xFF as Unicode has.
In my opinion, the best solution would be to use the "[value]" syntax that you're using for the other control characters for 0x80 through 0xFF as well. However, if you do want to convert those to characters, I'd use Encoding::Default, not Encoding::ASCII. ASCII only defines 0x00 through 0x7F, 0x80 and higher will come out as "?". Encoding::Default is whatever code page is defined for the language you have selected in Windows.
Combine all that, and here's what you'd end up with:
for (uint8_t i = 0; i < UART_G::message_length; i ++)
{
unsigned char mychar = UART_G::message[i];
if (mychar >= ' ' && mychar <= '~' && mychar != '[' && mychar != ']')
{
// Use the character directly for all ASCII printable characters,
// except '[' and ']', because those have a special meaning, below.
outputsb->Append((System::Char)(mychar));
}
else if (mychar >= 128)
{
// Non-ASCII characters, use the default encoding to convert to Unicode.
outputsb->Append(Encoding::Default->GetChars(UART_G::message, i, 1));
}
else
{
// Unprintable characters, use the byte value in brackets.
// Also do this for bracket characters, so there's no ambiguity
// what a bracket means in the logs.
outputsb->Append("[");
outputsb->Append((unsigned int)mychar);
outputsb->Append("]");
}
}
You are recieveing ascii value of the string .
See the Ascii chart
65 = A
80 = P
80 = P
76 = L
69 = E
Just write a function that converts the ascii value to string
Here is the code I came up with which resolved the issue:
static void logSend ()
{
StringBuilder^ outputsb = gcnew StringBuilder();
ASCIIEncoding^ ascii = gcnew ASCIIEncoding;
outputsb->Append("Sent ");
for (uint8_t i = 0; i < UART_G::message_length; i ++)
{
unsigned char mychar = UART_G::message[i];
if (
(mychar >= ' ' && mychar <= 'Z') || //Includes 0-9, A-Z.
(mychar >= '^' && mychar <= '~') || //Includes a-z.
(mychar >= 128 && mychar <= 254)) //I think these are okay.
{
outputsb->Append(ascii->GetString(UART_G::message, i, 1));
}
else
{
outputsb->Append("[");
outputsb->Append(mychar);
outputsb->Append("]");
}
}
log_line(outputsb->ToString());
}
I still appreciate any alternatives which are more efficient or simpler to read.

C# check to see if an input contains only lowercase letters a-z

I'm stuck on a task of trying to print words that contain only lowercase letters a-z. I have already stripped out an inputted string if it contains any number 0-9 and if it contains an Uppercase letter:
String[] textParts;
textParts = text.Split(delimChars);
for (int i = 0; i < textParts.Length; i++) //adds s to words list and checks for capitals
{
String s = textParts[i];
bool valid = true;
foreach (char c in textParts[i])
{
if (char.IsUpper(c))
{
valid = false;
break;
}
if (c >= '0' && c <= '9')
{
valid = false;
break;
}
if (char.IsPunctuation(c))
{
valid = false;
break;
}
}
if (valid) pageIn.words.Add(s);
This is my code so far. The last part I'm trying to check to see if a word contains any punctuation (it's not working) is there an easier way I could do this and how could I get the last part of my code to work?
P.S. I'm not that comfortable with using Regex.
Many Thanks,
Ellie
Without regex, you can use LINQ (might be less performant)
bool isOnlyLower = s.Count(c => Char.IsLower(c)) == s.Length;
Count will retrieve the number of char that are in lower in the following string. If it match the string's length, string is composed only of lowercase letters.
An alternative would be to check if there's any UpperCase :
bool isOnlyLower = !s.Any(c => Char.IsUpper(c));
var regex = new Regex("^[a-z]+$");
if (!regex.IsMatch(input))
{
// is't not only lower case letters, remove input
}
I'm not sure whether I get your question right, but shouldn't the following work?
for (int i = 0; i < textParts.Length; i++) //adds s to words list and checks for capitals
{
String s = textParts[i];
if(s.Equals(s.ToLower()))
{
// string is all lower
}
}

Converting a 1D pointer array (char) into a 2D pointer array (char) in Visual C++.

I am new to c++ programming I have to call a function with following arguments.
int Start (int argc, char **argv).
When I try to call the above function with the code below I get run time exceptions. Can some one help me out in resolving the above problem.
char * filename=NULL;
char **Argument1=NULL;
int Argument=0;
int j = 0;
int k = 0;
int i=0;
int Arg()
{
filename = "Globuss -dc bird.jpg\0";
for(i=0;filename[i]!=NULL;i++)
{
if ((const char *)filename[i]!=" ")
{
Argument1[j][k++] = NULL; // Here I get An unhandled
// exception of type
//'System.NullReferenceException'
// occurred
j++;
k=0;
}
else
{
(const char )Argument1[j][k] = filename [j]; // Here I also i get exception
k++;
Argument++;
}
}
Argument ++;
return 0;
}
Start (Argument,Argument1);
Two things:
char **Argument1=NULL;
This is pointer to pointer, You need to allocate it with some space in memory.
*Argument1 = new char[10];
for(i=0, i<10; ++i) Argument[i] = new char();
Don't forget to delete in the same style.
You appear to have no allocated any memory to you arrays, you just have a NULL pointer
char * filename=NULL;
char **Argument1=NULL;
int Argument=0;
int j = 0;
int k = 0;
int i=0;
int Arg()
{
filename = "Globuss -dc bird.jpg\0";
//I dont' know why you have 2D here, you are going to need to allocate
//sizes for both parts of the 2D array
**Argument1 = new char *[TotalFileNames];
for(int x = 0; x < TotalFileNames; x++)
Argument1[x] = new char[SIZE_OF_WHAT_YOU_NEED];
for(i=0;filename[i]!=NULL;i++)
{
if ((const char *)filename[i]!=" ")
{
Argument1[j][k++] = NULL; // Here I get An unhandled
// exception of type
//'System.NullReferenceException'
// occurred
j++;
k=0;
}
else
{
(const char )Argument1[j][k] = filename [j]; // Here I also i get exception
k++;
Argument++;
}
}
Argument ++;
return 0;
}
The first thing you have to do is to find the number of the strings you will have. Thats easy done with something like:
int len = strlen(filename);
int numwords = 1;
for(i = 0; i < len; i++) {
if(filename[i] == ' ') {
numwords++;
// eating up all spaces to not count following ' '
// dont checking if i exceeds len, because it will auto-stop at '\0'
while(filename[i] == ' ') i++;
}
}
In the above code i assume there will be at least one word in the filename (i.e. it wont be an empty string).
Now you can allocate memory for Argument1.
Argument1 = new char *[numwords];
After that you have two options:
use strtok (http://www.cplusplus.com/reference/clibrary/cstring/strtok/)
implement your function to split a string
That can be done like this:
int i,cur,last;
for(i = last = cur = 0; cur < len; cur++) {
while(filename[last] == ' ') { // last should never be ' '
last++;
}
if(filename[cur] == ' ') {
if(last < cur) {
Argument1[i] = new char[cur-last+1]; // +1 for string termination '\0'
strncpy(Argument1[i], &filename[last], cur-last);
last = cur;
}
}
}
The above code is not optimized, i just tried to make it as easy as possible to understand.
I also did not test it, but it should work. Assumptions i made:
string is null terminated
there is at least 1 word in the string.
Also whenever im referring to a string, i mean a char array :P
Some mistakes i noticed in your code:
in c/c++ " " is a pointer to a const char array which contains a space.
If you compare it with another " " you will compare the pointers to them. They may (and probably will) be different. Use strcmp (http://www.cplusplus.com/reference/clibrary/cstring/strcmp/) for that.
You should learn how to allocate dynamically memory. In c you can do it with malloc, in c++ with malloc and new (better use new instead of malloc).
Hope i helped!
PS if there is an error in my code tell me and ill fix it.

Need a program to reverse the words in a string

I asked this question in a few interviews. I want to know from the Stackoverflow readers as to what should be the answer to this question.
Such a seemingly simple question, but has been interpreted quite a few different ways.
if your definition of a "word" is a series of non-whitespace characters surrounded by a whitespace character, then in 5 second pseudocode you do:
var words = split(inputString, " ")
var reverse = new array
var count = words.count -1
var i = 0
while count != 0
reverse[i] = words[count]
count--
i++
return reverse
If you want to take into consideration also spaces, you can do it like that:
string word = "hello my name is";
string result="";
int k=word.size();
for (int j=word.size()-1; j>=0; j--)
{
while(word[j]!= ' ' && j>=0)
j--;
int end=k;
k=j+1;
int count=0;
if (j>=0)
{
int temp=j;
while (word[temp]==' '){
count++;
temp--;
}
j-=count;
}
else j=j+1;
result+=word.substr(k,end-k);
k-=count;
while(count!=0)
{
result+=' ';
count--;
}
}
It will print out for you "is name my hello"
Taken from something called "Hacking a Google Interview" that was somewhere on my computer ... don't know from where I got it but I remember I saw this exact question inside ... here is the answer:
Reverse the string by swapping the
first character with the last
character, the second with the
second-to-last character, and so on.
Then, go through the string looking
for spaces, so that you find where
each of the words is. Reverse each of
the words you encounter by again
swapping the first character with the
last character, the second character
with the second-to-last character, and
so on.
This came up in LessThanDot Programmer Puzzles
#include<stdio.h>
void reverse_word(char *,int,int);
int main()
{
char s[80],temp;
int l,i,k;
int lower,upper;
printf("Enter the ssentence\n");
gets(s);
l=strlen(s);
printf("%d\n",l);
k=l;
for(i=0;i<l;i++)
{
if(k<=i)
{temp=s[i];
s[i]=s[l-1-i];
s[l-1-i]=temp;}
k--;
}
printf("%s\n",s);
lower=0;
upper=0;
for(i=0;;i++)
{
if(s[i]==' '||s[i]=='\0')
{upper=i-1;
reverse_word(s,lower,upper);
lower=i+1;
}
if(s[i]=='\0')
break;
}
printf("%s",s);
return 0;
}
void reverse_word(char *s,int lower,int upper)
{
char temp;
//int i;
while(upper>lower)
{
temp=s[lower];
s[lower]=s[upper];
s[upper]=temp;
upper=upper-1;
lower=lower+1;
}
}
The following code (C++) will convert a string this is a test to test a is this:
string reverseWords(string str)
{
string result = "";
vector<string> strs;
stringstream S(str);
string s;
while (S>>s)
strs.push_back(s);
reverse(strs.begin(), strs.end());
if (strs.size() > 0)
result = strs[0];
for(int i=1; i<strs.size(); i++)
result += " " + strs[i];
return result;
}
PS: it's actually a google code jam question, more info can be found here.

Resources