Мне нужно решить эту проблему на С#: пользователь вводит целые числа из консоли (не фиксированное число int, а неограниченное количество int, столько, сколько он хочет) одно за другим, и когда пользователь вводит значение "x", программа должен остановиться и подсчитать и вывести количество четных чисел, содержащихся в строке.
Пример
Пользователь вводит эти целые числа из консоли:
2 5 8 4 1 6 9 2 5 x
и результат должен быть:
5
Это мой код:
using System;
public class TestNumericDataTypesOperations
{
public static void Main()
{
string[] a = new string[100];
int b=0;
int total = 0;
for (int i = 0; i < a.Length; i++)
{
a[i] = Console.ReadLine();
int b = int.Parse(a);
if (b % 2 == 0)
total++;
if (a[i] == "x")
{
break;
}
Console.WriteLine(total);
}
}
}
Я получаю ошибки CS1503 и CS0136 в строке 17 (int b = int.Parse(a);), предупреждение CS0219 в строке 10 (int b=0;) и предупреждение CS8601 в строке 16 (a[i] = Console.ReadLine();).
Спасибо!
ввод в одну строку?
Опечатка? Вы хотели разобрать a[i] вместо a? Вы забыли удалить b вне цикла, который не используете? Кажется, вы смотрите только на коды ошибок, но читаете ли вы сообщения об ошибках? О чем говорят вам эти сообщения и что вы о них спрашиваете?
Все что вы сказали выше верно и они порождают ошибки, но я не знаю как их исправить, чтобы получить желаемый результат.
@User_PI612: Сейчас самое время уточнить и уточнить, о чем вы спрашиваете. Если основной вопрос: «Как мне выполнить задание?» тогда это слишком широко, ваше задание — это часть вашей работы и, в конечном итоге, ваша ответственность. Мы можем помочь с конкретными проблемами, с которыми вы можете столкнуться на этом пути. (В показанном коде имеется несколько проблем.) Если основной вопрос касается конкретной ошибки в конкретной строке кода, укажите, какая ошибка и что вам сообщает сообщение об ошибке, и что вы спрашиваете об этой ошибке (например, почему вы не думаете, что это должно потерпеть неудачу).
Я пытаюсь исправить эти две ошибки [CS1503 и CS0136 в строке 17 ('''int b = int.Parse(a);''')], чтобы я мог подсчитывать четные числа из вмененной консоли строки.
@User_PI612: И о чем вам говорят эти сообщения об ошибках? Использовали ли вы свою любимую поисковую систему для поиска документации по этим кодам ошибок? Использовали ли вы свою любимую поисковую систему, чтобы найти другие примеры этих ошибок и способы их устранения? Можете ли вы указать, почему вы ожидаете, что эта строка кода не приведет к ошибке? Честно говоря, это звучит так, будто вы даже не читаете сообщение об ошибке, а просто сразу сдаетесь и просите нас сделать за вас домашнее задание.
Да, это была моя ошибка, их действительно 5.
@Дэвид: Конечно, я искал, но, поскольку до сих пор я не нашел ничего подобного, я продолжу поиск и, не сдаваясь, в конце концов решу эту проблему. Спасибо!
Мы не знаем эти номера CS наизусть.





Первый выпуск:
int.Parse(a);
a здесь массив, а не строка. Вместо этого вам нужно использовать конкретную запись в a.
Но есть еще более серьезная проблема, которую упустил компилятор: вы делаете это перед проверкой того, является ли ввод x, то есть вы ожидаете увидеть здесь нецелые значения хотя бы один раз. Это вызовет исключение, которое компилятор не сможет предвидеть во время работы программы. Вместо этого вам следует посмотреть на int.TryParse() и переместить эту часть после проверки, хочет ли пользователь выйти.
Тогда у нас есть предупреждение для этой строки:
int b = 0;
Проблема в том, что эта переменная никогда не используется. Вместо этого внутри цикла переменная объявляется заново: int b = int.Parse(a);. Либо удалите int из последней строки, либо (желательно) полностью удалите первую строку.
Наконец, у нас есть предупреждение для этой строки:
a[i] = Console.ReadLine();
Это относится к новой функции C# для проверок ссылок, допускающих значение NULL. Метод Console.Readline() намного старше этих проверок и по историческим причинам не помечает свой результат как ненулевой. Вы можете либо полностью отключить эти проверки (не рекомендуется), либо добавить специальный оператор прощения нуля:a[i] = Console.ReadLine()!;
В этой строке есть еще один последний вопрос:
Console.WriteLine(total);
Эта строка все еще находится внутри цикла, что означает, что она будет перезаписывать сумму для каждой записи. Вероятно, вы захотите сделать это только один раз, после цикла.
Но ради интереса, поскольку мы больше никогда не будем использовать исходные входные данные, я бы написал это так (массив не нужен):
public static void Main()
{
int total = 0;
string input;
while( (input = Console.ReadLine()) != "x")
{
if (int.TryParse(input, out int b) && b % 2 == 0)
total++;
}
Console.WriteLine(total);
}
И это полезно, чтобы продемонстрировать, как звонить int.TryParse()
Для большего удовольствия и для того, чтобы вы познакомились с некоторыми расширенными возможностями языка, мы могли бы добавить этот метод (нужен using System.Collections.Generic; вверху):
public static IEnumerable<int> ReadData()
{
string input;
while ( (input = Console.ReadLine()) != "x")
{
if (int.TryParse(input, out int i))
{
yield return i;
}
}
}
И тогда фактический программный метод является однострочным (требуется using System.Linq;):
public static void Main()
{
Console.WriteLine(ReadData().Count(i => i%2 == 0));
}
Примечание: вы можете избавиться от Where и перенести состояние в Count: ReadData().Count(item => item % 2 == 0)
@DmitryByченко Ох, конечно. Я всегда забываю, что Count() имеет перегрузку предиката.
@Джоэл Коегоорн: Большое спасибо!
Давайте выделим метод для чтения целых чисел:
// true, if we read an integer value (result)
// false, if user wants to stop adding items
private static bool TryReadInt(out int result) {
result = 0;
// We keep asking user until
while (true) {
string input = Console.ReadLine();
// user writes "x"
if (input.Trim() == "x") {
result = 0;
return false;
}
// Or provide a valid integer value
if (int.TryParse(input, out result))
return true;
Console.WriteLine("Not a valid integer, please, try again");
}
}
Затем мы можем реализовать процедуру Main следующим образом (обратите внимание, что нам не нужна никакая коллекция, поскольку все, что нам нужно сделать, это посчитать, а не предоставить все четные числа):
public static void Main() {
int total = 0;
while (TryReadInt(out var item)) {
if (item % 2 == 0)
total += 1;
}
Console.WriteLine(total);
}
Не могли бы мы переместить вызов TryReadInt в условие цикла while вместо true ? Когда я это делаю, я всегда чувствую себя немного грязным while(true) { if (!condition) break; } :D => dotnetfiddle.net/XP5Ila
@Филдор: Спасибо! while(true) { if () break; } было действительно некрасиво.
Если бы мне нужно было извлечь чтение, я бы переместил туда все чтения, чтобы оно возвращало массив или перечисляемое, вместо того, чтобы использовать out. Хм... возможно, я напишу это в конце своего ответа.
@Joel Coehoorn: Вы совершенно правы, и тогда вы можете запросить это IEnumerable<int> с помощью Linq... Но это компактное и легко читаемое решение может показаться слишком сложным для ОП.
Подсказки: 1) для
int.Parse(a)какой типaи как вы ожидаете, что он будет анализироваться как одно целое число? 2) Кажется, вы дважды заявляетеb. Вы намеревались это сделать? Я бы, вероятно, посоветовал вам отключить ссылочные типы, допускающие значение NULL, пока вы не освоитесь с основами C#.