This question already has answers here:
"The argument type 'String?' can't be assigned to the parameter type 'String'" when using stdin.readLineSync()
(3 answers)
Closed 1 year ago.
I recently got into flutter and dart and I've been writing basic programs. Just this morning I ran into an error when trying to convert user input from a string into an integer so I could perform a mathematical operation. Here's the code.
import "dart:io";
import "dart:math";
import "dart:convert";
void main() {
print("Enter a number: ");
String num1 = stdin.readLineSync();
print("Enter a second number");
String num2 = stdin.readLineSync();
print(int.parse(num1) + int.parse(num2));
}
Surprisingly this runs well on the online dart compiler and interpreter. (replit)
but when I run it on vscode, I get this error
"Error: A value of type 'String?' can't be assigned to a variable of type 'String' because 'String?' is nullable and 'String' isn't.
String num2 = stdin.readLineSync();"
Whichever data type I use, I get the same error. be it var, or string, or int or double.
I tried another method of conversion but its the same thing. works on the online compiler, doesn't work on my machine. here's the code.
import "dart:io";
import "dart:math";
import "dart:convert";
void main() {
print("Enter a number: ");
var num1 = stdin.readLineSync();
var num2 = int.parse(num1);
print("Enter a second number");
var num3 = stdin.readLineSync();
var num4 = int.parse(num3);
print(num2 + num4);
}
stdin.readLineSync() returns a String?. Types ending in a ? are nullable. String? means either String or null.
Also int.parse takes a parameter of type String not String? so you cannot pass a value to it which might be null. There are a few different approaches you can take to work around this. One thing you can do is check if they are not null in an if statement, and in doing so the values of num1 and num2 will be promoted to String within the body of the if statement. Another approach is to use the ?? operator on num1 and num2, which is called the "if null" operator and allows you to provide a default value in the event that num1 or num2 is null.
import "dart:io";
import "dart:math";
import "dart:convert";
void main() {
print("Enter a number: ");
// set type to String? (you can also use var or final)
String? num1 = stdin.readLineSync();
print("Enter a second number");
String? num2 = stdin.readLineSync();
// check for null values before using num1 and num2
if (num1 != null && num2 != null) {
print(int.parse(num1) + int.parse(num2));
}
// alternatively you can convert the values to String
// using the ?? operator. if the value of num1 is null
// then you will get '' (empty string) instead.
print(int.parse(num1 ?? '') + int.parse(num2 ?? ''));
}
I am not familiar with replit, but it may be using an older version of dart language. dart version 2.12 introduced features related to null safety.
See also:
https://medium.com/dartlang/announcing-dart-2-12-499a6e689c87
https://dart.dev/null-safety/understanding-null-safety
https://dart.dev/codelabs/null-safety
Related
This question already has answers here:
"The argument type 'String?' can't be assigned to the parameter type 'String'" when using stdin.readLineSync()
(3 answers)
Closed 6 months ago.
I am trying to parse an input with the type 'String?' into a double, but it is saying that -
The argument type 'String?' can't be assigned to the parameter type 'String'.
stdout.write("Enter the first number - ");
String? vari = stdin.readLineSync();
var first = int.parse(vari);
Change it to:
int? first = int.tryParse(vari.toString());
This is because String? is nullable, vs String.
.parse functions require non-nullable Strings.
tryParse returns an int if the string is parsable, and returns null if it can't be parsed. This is why I changed var first to int? first.
You can check afterwards if first is null or not. You can also perform this check before parsing it, and your code would look like this:
String? vari = stdin.readLineSync();
if (vari != null) var first = int.parse(vari);
This would work.
I recently started dart programing, I encountered a issue while doing it,
I was doing it by referring this website https://hackmd.io/#kuzmapetrovich/S1x90jWGP
Error: A value of type 'String?' can't be assigned to a variable of type 'num'.
My code :
import 'dart:io';
void main() {
print('Enter a number');
var num1 = stdin.readLineSync();
var num2= 100-num1;
}
can anyone tell whats the issue and how to fix.
you can parse String into
int
var num2 = 100 - int.parse(num1!);
or double
var num2 = 100 - double.parse(num1!);
So stdin.readLineSync() reads your console input and will store it to num1 of type var. As you can see in the documentation, stdin.readLineSync() returns a String?.
Because the data type of var variables is resolved during runtime, num1 will be of type String? after assigning the console input to it.
So the problem of your code is, that you try to subtract 100 from a string, which is not possible.
To solve this issue you should better convert your input into a numerical type, like int or double. But be careful! Your input could also contain character that can't be converted to a number. One solution could look like following:
void main() {
print('Enter a number');
var input = stdin.readLineSync();
var num1 = double.parse(input);
if (num1 != null){
var num2 = 100 - num1;
}else{
// num1 could not be converted to a double
// handle exception here
}
}
For the beginning, I recommend you to use data types in your code instead of var and val. Maybe reading something about dart's type system may also be helpful.
I keep getting this error => "The operator '+' isn't defined for the type 'Object'. (view docs). Try defining the operator '+'."
How could I define it?
import 'dart:math';
bool isArmstrongNumber(int number) {
var numberString = number.toString();
return number ==
numberString.split("").fold(0,
(prev, curr) => prev! + pow(int.parse(curr), numberString.length));
}
main() {
var result = isArmstrongNumber(153);
print(result);
}
fold in Dart can have some problems when it comes to automatically determine what type it should return and handle. In these cases, we need to manually enter the type like this (fold<int>()):
import 'dart:math';
bool isArmstrongNumber(int number) {
final numberString = number.toString();
return number ==
numberString.split("").fold<int>(
0,
(prev, curr) =>
prev + pow(int.parse(curr), numberString.length).toInt(),
);
}
void main() {
final result = isArmstrongNumber(153);
print(result); // true
}
I also fixed a problem where pow returns num which is a problem. In this case, we can safely just cast it to int without issues.
Details about this problem with fold
The problem here is that Dart tries to guess the generic of the fold based on the expected returned type of the method. Since the == operator expects an Object to compare against, fold will also expect to just return Object and the generic ends up being fold<Object>.
This is not a problem for the first parameter since int is an Object. But it becomes a problem with your second argument where you expect an int object and not Object since Object does not have the + operator.
This question already has answers here:
"The argument type 'String?' can't be assigned to the parameter type 'String'" when using stdin.readLineSync()
(3 answers)
Closed 1 year ago.
I'm new at dart. I think that it's about the new dart version that I can't assign String to stdin.readLineSync(). Can Someone Pls tell me the alternatives?
This is just a basic calculator where I'm trying to add two numbers.
import 'dart:io';
import 'dart:math';
void main() {
print("Enter first number: ");
String? num1 = stdin.readLineSync();
print("Enter second number: ");
String? num2 = stdin.readLineSync();
print(num1 + num2);
}
This is the alternative way how you do:
In Dart programming language, you can take standard input from the user through the console via the use of .readLineSync() function.
import 'dart:io';
void main()
{
print("Enter first number");
int? n1 = int.parse(stdin.readLineSync()!);
print("Enter second number");
int? n2 = int.parse(stdin.readLineSync()!);
int sum = n1 + n2;
print("Sum is $sum");
}
and here it is clearly explained about your problem "The argument type 'String?' can't be assigned to the parameter type 'String'" when using stdin.readLineSync()
How do I get the last n-characters in a string?
I've tried using:
var string = 'Dart is fun';
var newString = string.substring(-5);
But that does not seem to be correct
var newString = string.substring(string.length - 5);
Create an extension:
extension E on String {
String lastChars(int n) => substring(length - n);
}
Usage:
var source = 'Hello World';
var output = source.lastChars(5); // 'World'
While #Alexandre Ardhuin is correct, it is important to note that if the string has fewer than n characters, an exception will be raised:
Uncaught Error: RangeError: Value not in range: -5
It would behoove you to check the length before running it that way
String newString(String oldString, int n) {
if (oldString.length >= n) {
return oldString.substring(oldString.length - n)
} else {
// return whatever you want
}
}
While you're at it, you might also consider ensuring that the given string is not null.
oldString ??= '';
If you like one-liners, another options would be:
String newString = oldString.padLeft(n).substring(max(oldString.length - n, 0)).trim()
If you expect it to always return a string with length of n, you could pad it with whatever default value you want (.padLeft(n, '0')), or just leave off the trim().
At least, as of Dart SDK 2.8.1, that is the case. I know they are working on improving null safety and this might change in the future.
var newString = string.substring((string.length - 5).clamp(0, string.length));
note: I am using clamp in order to avoid Value Range Error. By that you are also immune to negative n-characters if that is somehow calculated.
In fact I wonder that dart does not have such clamp implemented within the substring method.
If you want to be null aware, just use:
var newString = string?.substring((string.length - 5).clamp(0, string.length));
I wrote my own solution to get any no of last n digits from a string of unknown length, for example the 5th to the last digit from an n digit string,
String bin='408 408 408 408 408 1888';// this is the your string
// this function is to remove space from the string and then reverse the
string, then convert it to a list
List reversed=bin.replaceAll(" ","").split('').reversed.toList();
//and then get the 0 to 4th digit meaning if you want to get say 6th to last digit, just pass 0,6 here and so on. This second reverse function, return the string to its initial arrangement
var list = reversed.sublist(0,4).reversed.toList();
var concatenate = StringBuffer();
// this function is to convert the list back to string
list.forEach((item){
concatenate.write(item);
});
print(concatenate);// concatenate is the string you need